lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <763200e4f55197da44789b97fd5379ae8bf32c08.camel@gmail.com>
Date: Thu, 04 Dec 2025 08:57:10 -0800
From: Eduard Zingerman <eddyz87@...il.com>
To: Ihor Solodrai <ihor.solodrai@...ux.dev>, Alexei Starovoitov
 <ast@...nel.org>,  Daniel Borkmann <daniel@...earbox.net>, Andrii Nakryiko
 <andrii@...nel.org>, Martin KaFai Lau <martin.lau@...ux.dev>,  Song Liu
 <song@...nel.org>, Yonghong Song <yonghong.song@...ux.dev>, John Fastabend	
 <john.fastabend@...il.com>, KP Singh <kpsingh@...nel.org>, Stanislav
 Fomichev	 <sdf@...ichev.me>, Hao Luo <haoluo@...gle.com>, Jiri Olsa
 <jolsa@...nel.org>,  Nathan Chancellor	 <nathan@...nel.org>, Nicolas Schier
 <nicolas.schier@...ux.dev>, Nick Desaulniers
 <nick.desaulniers+lkml@...il.com>, Bill Wendling <morbo@...gle.com>, Justin
 Stitt	 <justinstitt@...gle.com>, Alan Maguire <alan.maguire@...cle.com>,
 Donglin Peng	 <dolinux.peng@...il.com>
Cc: bpf@...r.kernel.org, dwarves@...r.kernel.org,
 linux-kernel@...r.kernel.org, 	linux-kbuild@...r.kernel.org
Subject: Re: [PATCH bpf-next v2 4/4] resolve_btfids: change in-place update
 with raw binary output

On Wed, 2025-12-03 at 21:13 -0800, Ihor Solodrai wrote:
> On 12/1/25 11:55 AM, Eduard Zingerman wrote:
> > On Thu, 2025-11-27 at 10:52 -0800, Ihor Solodrai wrote:
> > > Currently resolve_btfids updates .BTF_ids section of an ELF file
> > > in-place, based on the contents of provided BTF, usually within the
> > > same input file, and optionally a BTF base.
> > > 
> 
> Hi Eduard, thank you for the review.
> 
> > > This patch changes resolve_btfids behavior to enable BTF
> > > transformations as part of its main operation. To achieve this
> > > in-place ELF write in resolve_btfids is replaced with generation of
> > > the following binaries:
> > >   * ${1}.btf with .BTF section data
> > >   * ${1}.distilled_base.btf with .BTF.base section data (for
> > >     out-of-tree modules)
> > >   * ${1}.btf_ids with .BTF_ids section data, if it exists in ${1}
> > 
> > Nit: use ${1}.BTF / ${1}.BTF.base / ${1}.BTF_ids, so that each file is
> >      named by it's corresponding section?
> 
> Sure, makes sense.
> 
> > 
> > > 
> > > The execution of resolve_btfids and consumption of its output is
> > > orchestrated by scripts/gen-btf.sh introduced in this patch.
> > > 
> > > The rationale for this approach is that updating ELF in-place with
> > > libelf API is complicated and bug-prone, especially in the context of
> > > the kernel build. On the other hand applying objcopy to manipulate ELF
> > > sections is simpler and more reliable.
> > 
> > Nit: more context needed, as is the statement raises questions but not
> >      answers them.
> 
> Would you like to see more details about why using libelf is complicated?
> I don't follow what's unclear here, sorry...

The claim here is: "libelf API is complicated and bug-prone ... in
context of the kernel build". This is a very vague wording.
The decision to rely on objcopy/linker comes from a specific needs
outlined by Andrii in an off-list discussion. It will be good to have
this context captured in the commit message, instead of bluntly
stating that libelf is bug-prone.

> > > There are two distinct paths for BTF generation and resolve_btfids
> > > application in the kernel build: for vmlinux and for kernel modules.
> > > 
> > > For the vmlinux binary a .BTF section is added in a roundabout way to
> > > ensure correct linking (details below). The patch doesn't change this
> > > approach, only the implementation is a little different.
> > > 
> > > Before this patch it worked like follows:
> > > 
> > >   * pahole consumed .tmp_vmlinux1 [1] and added .BTF section with
> > >     llvm-objcopy [2] to it
> > >   * then everything except the .BTF section was stripped from .tmp_vmlinux1
> > >     into a .tmp_vmlinux1.bpf.o object [1], later linked into vmlinux
> > >   * resolve_btfids was executed later on vmlinux.unstripped [3],
> > >     updating it in-place
> > > 
> > > After this patch gen-btf.sh implements the following:
> > > 
> > >   * pahole consumes .tmp_vmlinux1 and produces a *detached* file with
> > >     raw BTF data
> > >   * resolve_btfids consumes .tmp_vmlinux1 and detached BTF to produce
> > >     (potentially modified) .BTF, and .BTF_ids sections data
> > >   * a .tmp_vmlinux1.bpf.o object is then produced with objcopy copying
> > >     BTF output of resolve_btfids
> > >   * .BTF_ids data gets embedded into vmlinux.unstripped in
> > >     link-vmlinux.sh by objcopy --update-section
> > > 
> > > For the kernel modules creating special .bpf.o file is not necessary,
> > > and so embedding of sections data produced by resolve_btfids is
> > > straightforward with the objcopy.
> > > 
> > > With this patch an ELF file becomes effectively read-only within
> > > resolve_btfids, which allows to delete elf_update() call and satelite
> > > code (like compressed_section_fix [4]).
> > > 
> > > Endianness handling of .BTF_ids data is also changed. Previously the
> > > "flags" part of the section was bswapped in sets_patch() [5], and then
> > > Elf_Type was modified before elf_update() to signal to libelf that
> > > bswap may be necessary. With this patch we explicitly bswap entire
> > > data buffer on load and on dump.
> > > 
> > > [1] https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf.git/tree/scripts/link-vmlinux.sh#n115
> > > [2] https://git.kernel.org/pub/scm/devel/pahole/pahole.git/tree/btf_encoder.c#n1835
> > > [3] https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf.git/tree/scripts/link-vmlinux.sh#n285
> > 
> > Nit: these links are moving target, should refer to a commit or a tag.
> 
> Acked
> 
> > 
> > > [4] https://lore.kernel.org/bpf/20200819092342.259004-1-jolsa@kernel.org/
> > > [5] https://lore.kernel.org/bpf/cover.1707223196.git.vmalik@redhat.com/
> > > 
> > > Signed-off-by: Ihor Solodrai <ihor.solodrai@...ux.dev>
> > > ---
> > >  MAINTAINERS                          |   1 +
> > >  scripts/Makefile.modfinal            |   5 +-
> > >  scripts/gen-btf.sh                   | 167 ++++++++++++++++++++
> > >  scripts/link-vmlinux.sh              |  42 +-----
> > >  tools/bpf/resolve_btfids/main.c      | 218 +++++++++++++++++----------
> > >  tools/testing/selftests/bpf/Makefile |   5 +
> > >  6 files changed, 317 insertions(+), 121 deletions(-)
> > >  create mode 100755 scripts/gen-btf.sh
> > 
> > Since resolve_btfids is now responsible for distilled base generation,
> > does Makefile.btf need modification to remove "--btf_features=distilled_base"?
> 
> Yes, good catch.
> 
> > 
> > > 
> > > diff --git a/MAINTAINERS b/MAINTAINERS
> > > index 48aabeeed029..5cd34419d952 100644
> > > --- a/MAINTAINERS
> > > +++ b/MAINTAINERS
> > > @@ -4672,6 +4672,7 @@ F:	net/sched/act_bpf.c
> > >  F:	net/sched/cls_bpf.c
> > >  F:	samples/bpf/
> > >  F:	scripts/bpf_doc.py
> > > +F:	scripts/gen-btf.sh
> > >  F:	scripts/Makefile.btf
> > >  F:	scripts/pahole-version.sh
> > >  F:	tools/bpf/
> > > diff --git a/scripts/Makefile.modfinal b/scripts/Makefile.modfinal
> > > index 542ba462ed3e..3862fdfa1267 100644
> > > --- a/scripts/Makefile.modfinal
> > > +++ b/scripts/Makefile.modfinal
> > > @@ -38,9 +38,8 @@ quiet_cmd_btf_ko = BTF [M] $@
> > >        cmd_btf_ko = 							\
> > >  	if [ ! -f $(objtree)/vmlinux ]; then				\
> > >  		printf "Skipping BTF generation for %s due to unavailability of vmlinux\n" $@ 1>&2; \
> > > -	else								\
> > > -		LLVM_OBJCOPY="$(OBJCOPY)" $(PAHOLE) -J $(PAHOLE_FLAGS) $(MODULE_PAHOLE_FLAGS) --btf_base $(objtree)/vmlinux $@; \
> > > -		$(RESOLVE_BTFIDS) -b $(objtree)/vmlinux $@;		\
> > > +	else	\
> > > +		$(srctree)/scripts/gen-btf.sh --btf_base $(objtree)/vmlinux $@; \
> > >  	fi;
> > >  
> > >  # Same as newer-prereqs, but allows to exclude specified extra dependencies
> > > diff --git a/scripts/gen-btf.sh b/scripts/gen-btf.sh
> > > new file mode 100755
> > > index 000000000000..2dfb7ab289ca
> > > --- /dev/null
> > > +++ b/scripts/gen-btf.sh
> > > @@ -0,0 +1,167 @@
> > > +#!/bin/bash
> > > +# SPDX-License-Identifier: GPL-2.0
> > > +# Copyright (c) 2025 Meta Platforms, Inc. and affiliates.
> > > +#
> > > +# This script generates BTF data for the provided ELF file.
> > > +#
> > > +# Kernel BTF generation involves these conceptual steps:
> > > +#   1. pahole generates BTF from DWARF data
> > > +#   2. resolve_btfids applies kernel-specific btf2btf
> > > +#      transformations and computes data for .BTF_ids section
> > > +#   3. the result gets linked/objcopied into the target binary
> > > +#
> > > +# How step (3) should be done differs between vmlinux, and
> > > +# kernel modules, which is the primary reason for the existence
> > > +# of this script.
> > > +#
> > > +# For modules the script expects vmlinux passed in as --btf_base.
> > > +# Generated .BTF, .BTF.base and .BTF_ids sections become embedded
> > > +# into the input ELF file with objcopy.
> > > +#
> > > +# For vmlinux the input file remains unchanged and two files are produced:
> > > +#   - ${1}.btf.o ready for linking into vmlinux
> > > +#   - ${1}.btf_ids with .BTF_ids data blob
> > > +# This output is consumed by scripts/link-vmlinux.sh
> > > +
> > > +set -e
> > > +
> > > +usage()
> > > +{
> > > +	echo "Usage: $0 [--btf_base <file>] <target ELF file>"
> > > +	exit 1
> > > +}
> > > +
> > > +BTF_BASE=""
> > > +
> > > +while [ $# -gt 0 ]; do
> > > +	case "$1" in
> > > +	--btf_base)
> > > +		BTF_BASE="$2"
> > > +		shift 2
> > > +		;;
> > > +	-*)
> > > +		echo "Unknown option: $1" >&2
> > > +		usage
> > > +		;;
> > > +	*)
> > > +		break
> > > +		;;
> > > +	esac
> > > +done
> > > +
> > > +if [ $# -ne 1 ]; then
> > > +	usage
> > > +fi
> > > +
> > > +ELF_FILE="$1"
> > > +shift
> > > +
> > > +is_enabled() {
> > > +	grep -q "^$1=y" ${objtree}/include/config/auto.conf
> > > +}
> > > +
> > > +info()
> > > +{
> > > +	printf "  %-7s %s\n" "${1}" "${2}"
> > > +}
> > > +
> > > +case "${KBUILD_VERBOSE}" in
> > > +*1*)
> > > +	set -x
> > > +	;;
> > > +esac
> > > +
> > > +if ! is_enabled CONFIG_DEBUG_INFO_BTF; then
> > > +	exit 0
> > > +fi
> > > +
> > > +gen_btf_data()
> > > +{
> > > +	info BTF "${ELF_FILE}"
> > > +	btf1="${ELF_FILE}.btf.1"
> > > +	${PAHOLE} -J ${PAHOLE_FLAGS}			\
> > > +		${BTF_BASE:+--btf_base ${BTF_BASE}}	\
> > > +		--btf_encode_detached=${btf1}		\
> > > +		"${ELF_FILE}"
> > > +
> > > +	info BTFIDS "${ELF_FILE}"
> > > +	RESOLVE_BTFIDS_OPTS=""
> > > +	if is_enabled CONFIG_WERROR; then
> > > +		RESOLVE_BTFIDS_OPTS+=" --fatal_warnings "
> > > +	fi
> > > +	if [ -n "${KBUILD_VERBOSE}" ]; then
> > > +		RESOLVE_BTFIDS_OPTS+=" -v "
> > > +	fi
> > > +	${RESOLVE_BTFIDS} ${RESOLVE_BTFIDS_OPTS}	\
> > > +		${BTF_BASE:+--btf_base ${BTF_BASE}}	\
> > > +		--btf ${btf1} "${ELF_FILE}"
> > > +}
> > > +
> > > +gen_btf_o()
> > > +{
> > > +	local btf_data=${ELF_FILE}.btf.o
> > > +
> > > +	# Create ${btf_data} which contains just .BTF section but no symbols. Add
> > > +	# SHF_ALLOC because .BTF will be part of the vmlinux image. --strip-all
> > > +	# deletes all symbols including __start_BTF and __stop_BTF, which will
> > > +	# be redefined in the linker script.
> > > +	info OBJCOPY "${btf_data}"
> > > +	echo "" | ${CC} -c -x c -o ${btf_data} -
> > > +	${OBJCOPY} --add-section .BTF=${ELF_FILE}.btf \
> > > +		--set-section-flags .BTF=alloc,readonly ${btf_data}
> > > +	${OBJCOPY} --only-section=.BTF --strip-all ${btf_data}
> > > +
> > > +	# Change e_type to ET_REL so that it can be used to link final vmlinux.
> > > +	# GNU ld 2.35+ and lld do not allow an ET_EXEC input.
> > > +	if is_enabled CONFIG_CPU_BIG_ENDIAN; then
> > > +		et_rel='\0\1'
> > > +	else
> > > +		et_rel='\1\0'
> > > +	fi
> > > +	printf "${et_rel}" | dd of="${btf_data}" conv=notrunc bs=1 seek=16 status=none
> > > +}
> > > +
> > > +embed_btf_data()
> > > +{
> > > +	info OBJCOPY "${ELF_FILE}"
> > > +	${OBJCOPY} --add-section .BTF=${ELF_FILE}.btf ${ELF_FILE}
> > > +
> > > +	# a module might not have a .BTF_ids or .BTF.base section
> > > +	local btf_base="${ELF_FILE}.distilled_base.btf"
> > > +	if [ -f "${btf_base}" ]; then
> > > +		${OBJCOPY} --add-section .BTF.base=${btf_base} ${ELF_FILE}
> > > +	fi
> > > +	local btf_ids="${ELF_FILE}.btf_ids"
> > > +	if [ -f "${btf_ids}" ]; then
> > > +		${OBJCOPY} --update-section .BTF_ids=${btf_ids} ${ELF_FILE}
> > > +	fi
> > > +}
> > > +
> > > +cleanup()
> > > +{
> > > +	rm -f "${ELF_FILE}.btf.1"
> > > +	rm -f "${ELF_FILE}.btf"
> > > +	if [ "${BTFGEN_MODE}" = "module" ]; then
> > > +		rm -f "${ELF_FILE}.distilled_base.btf"
> > > +		rm -f "${ELF_FILE}.btf_ids"
> > > +	fi
> > > +}
> > > +trap cleanup EXIT
> > > +
> > > +BTFGEN_MODE="vmlinux"
> > > +if [ -n "${BTF_BASE}" ]; then
> > > +	BTFGEN_MODE="module"
> > > +fi
> > > +
> > > +gen_btf_data
> > > +
> > > +case "${BTFGEN_MODE}" in
> > > +vmlinux)
> > > +	gen_btf_o
> > > +	;;
> > > +module)
> > > +	embed_btf_data
> > > +	;;
> > > +esac
> > > +
> > > +exit 0
> > > diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh
> > > index 433849ff7529..5bea8795f96d 100755
> > > --- a/scripts/link-vmlinux.sh
> > > +++ b/scripts/link-vmlinux.sh
> > > @@ -105,34 +105,6 @@ vmlinux_link()
> > >  		${kallsymso} ${btf_vmlinux_bin_o} ${arch_vmlinux_o} ${ldlibs}
> > >  }
> > >  
> > > -# generate .BTF typeinfo from DWARF debuginfo
> > > -# ${1} - vmlinux image
> > > -gen_btf()
> > > -{
> > > -	local btf_data=${1}.btf.o
> > > -
> > > -	info BTF "${btf_data}"
> > > -	LLVM_OBJCOPY="${OBJCOPY}" ${PAHOLE} -J ${PAHOLE_FLAGS} ${1}
> > > -
> > > -	# Create ${btf_data} which contains just .BTF section but no symbols. Add
> > > -	# SHF_ALLOC because .BTF will be part of the vmlinux image. --strip-all
> > > -	# deletes all symbols including __start_BTF and __stop_BTF, which will
> > > -	# be redefined in the linker script. Add 2>/dev/null to suppress GNU
> > > -	# objcopy warnings: "empty loadable segment detected at ..."
> > > -	${OBJCOPY} --only-section=.BTF --set-section-flags .BTF=alloc,readonly \
> > > -		--strip-all ${1} "${btf_data}" 2>/dev/null
> > > -	# Change e_type to ET_REL so that it can be used to link final vmlinux.
> > > -	# GNU ld 2.35+ and lld do not allow an ET_EXEC input.
> > > -	if is_enabled CONFIG_CPU_BIG_ENDIAN; then
> > > -		et_rel='\0\1'
> > > -	else
> > > -		et_rel='\1\0'
> > > -	fi
> > > -	printf "${et_rel}" | dd of="${btf_data}" conv=notrunc bs=1 seek=16 status=none
> > > -
> > > -	btf_vmlinux_bin_o=${btf_data}
> > > -}
> > > -
> > >  # Create ${2}.o file with all symbols from the ${1} object file
> > >  kallsyms()
> > >  {
> > > @@ -204,6 +176,7 @@ if is_enabled CONFIG_ARCH_WANTS_PRE_LINK_VMLINUX; then
> > >  fi
> > >  
> > >  btf_vmlinux_bin_o=
> > > +btfids_vmlinux=
> > >  kallsymso=
> > >  strip_debug=
> > >  generate_map=
> > > @@ -224,11 +197,13 @@ if is_enabled CONFIG_KALLSYMS || is_enabled CONFIG_DEBUG_INFO_BTF; then
> > >  fi
> > >  
> > >  if is_enabled CONFIG_DEBUG_INFO_BTF; then
> > > -	if ! gen_btf .tmp_vmlinux1; then
> > > +	if ! ${srctree}/scripts/gen-btf.sh .tmp_vmlinux1; then
> > 
> > Nit: maybe pass output file names as parameters for get-btf.sh?
> 
> I don't see a point in that. The script and callsite will become
> more complicated, but what is the benefit?

In order to avoid implicit naming conventions.  Hence, the reader of
the script code has clear understanding about in and out parameters.

> > 
> > >  		echo >&2 "Failed to generate BTF for vmlinux"
> > >  		echo >&2 "Try to disable CONFIG_DEBUG_INFO_BTF"
> > >  		exit 1
> > >  	fi
> > > +	btf_vmlinux_bin_o=.tmp_vmlinux1.btf.o
> > > +	btfids_vmlinux=.tmp_vmlinux1.btf_ids
> > >  fi
> > >  
> > >  if is_enabled CONFIG_KALLSYMS; then
> > > @@ -281,14 +256,9 @@ fi
> > >  
> > >  vmlinux_link "${VMLINUX}"
> > >  
> > > -# fill in BTF IDs
> > >  if is_enabled CONFIG_DEBUG_INFO_BTF; then
> > > -	info BTFIDS "${VMLINUX}"
> > > -	RESOLVE_BTFIDS_ARGS=""
> > > -	if is_enabled CONFIG_WERROR; then
> > > -		RESOLVE_BTFIDS_ARGS=" --fatal_warnings "
> > > -	fi
> > > -	${RESOLVE_BTFIDS} ${RESOLVE_BTFIDS_ARGS} "${VMLINUX}"
> > > +	info OBJCOPY ${btfids_vmlinux}
> > > +	${OBJCOPY} --update-section .BTF_ids=${btfids_vmlinux} ${VMLINUX}
> > >  fi
> > 
> > Nit: Maybe do this in get-btf.sh as for modules?
> >      To avoid checking for CONFIG_DEBUG_INFO_BTF in two places.
> 
> IIRC we can't do that, because we have to update .BTF_ids after all
> the linking steps. I'll double check.
> 
> > 
> > >  
> > >  mksysmap "${VMLINUX}" System.map
> > > diff --git a/tools/bpf/resolve_btfids/main.c b/tools/bpf/resolve_btfids/main.c
> > > index c60d303ca6ed..b8df6256e29e 100644
> > > --- a/tools/bpf/resolve_btfids/main.c
> > > +++ b/tools/bpf/resolve_btfids/main.c
> > > @@ -71,9 +71,11 @@
> > >  #include <fcntl.h>
> > >  #include <errno.h>
> > >  #include <linux/btf_ids.h>
> > > +#include <linux/kallsyms.h>
> > >  #include <linux/rbtree.h>
> > >  #include <linux/zalloc.h>
> > >  #include <linux/err.h>
> > > +#include <linux/limits.h>
> > >  #include <bpf/btf.h>
> > >  #include <bpf/libbpf.h>
> > >  #include <subcmd/parse-options.h>
> > > @@ -124,6 +126,7 @@ struct object {
> > >  
> > >  	struct btf *btf;
> > >  	struct btf *base_btf;
> > > +	bool distilled_base;
> > >  
> > >  	struct {
> > >  		int		 fd;
> > > @@ -308,42 +311,16 @@ static struct btf_id *add_symbol(struct rb_root *root, char *name, size_t size)
> > >  	return btf_id;
> > >  }
> > >  
> > > -/* Older libelf.h and glibc elf.h might not yet define the ELF compression types. */
> > > -#ifndef SHF_COMPRESSED
> > > -#define SHF_COMPRESSED (1 << 11) /* Section with compressed data. */
> > > -#endif
> > > -
> > > -/*
> > > - * The data of compressed section should be aligned to 4
> > > - * (for 32bit) or 8 (for 64 bit) bytes. The binutils ld
> > > - * sets sh_addralign to 1, which makes libelf fail with
> > > - * misaligned section error during the update:
> > > - *    FAILED elf_update(WRITE): invalid section alignment
> > > - *
> > > - * While waiting for ld fix, we fix the compressed sections
> > > - * sh_addralign value manualy.
> > > - */
> > > -static int compressed_section_fix(Elf *elf, Elf_Scn *scn, GElf_Shdr *sh)
> > > +static void bswap_32_data(void *data, u32 nr_bytes)
> > >  {
> > > -	int expected = gelf_getclass(elf) == ELFCLASS32 ? 4 : 8;
> > > +	u32 cnt, i;
> > > +	u32 *ptr;
> > >  
> > > -	if (!(sh->sh_flags & SHF_COMPRESSED))
> > > -		return 0;
> > > +	cnt = nr_bytes / sizeof(u32);
> > > +	ptr = data;
> > >  
> > > -	if (sh->sh_addralign == expected)
> > > -		return 0;
> > > -
> > > -	pr_debug2(" - fixing wrong alignment sh_addralign %u, expected %u\n",
> > > -		  sh->sh_addralign, expected);
> > > -
> > > -	sh->sh_addralign = expected;
> > > -
> > > -	if (gelf_update_shdr(scn, sh) == 0) {
> > > -		pr_err("FAILED cannot update section header: %s\n",
> > > -			elf_errmsg(-1));
> > > -		return -1;
> > > -	}
> > > -	return 0;
> > > +	for (i = 0; i < cnt; i++)
> > > +		ptr[i] = bswap_32(ptr[i]);
> > >  }
> > >  
> > >  static int elf_collect(struct object *obj)
> > > @@ -364,7 +341,7 @@ static int elf_collect(struct object *obj)
> > >  
> > >  	elf_version(EV_CURRENT);
> > >  
> > > -	elf = elf_begin(fd, ELF_C_RDWR_MMAP, NULL);
> > > +	elf = elf_begin(fd, ELF_C_READ_MMAP_PRIVATE, NULL);
> > >  	if (!elf) {
> > >  		close(fd);
> > >  		pr_err("FAILED cannot create ELF descriptor: %s\n",
> > > @@ -427,21 +404,20 @@ static int elf_collect(struct object *obj)
> > >  			obj->efile.symbols_shndx = idx;
> > >  			obj->efile.strtabidx     = sh.sh_link;
> > >  		} else if (!strcmp(name, BTF_IDS_SECTION)) {
> > > +			/*
> > > +			 * If target endianness differs from host, we need to bswap32
> > > +			 * the .BTF_ids section data on load, because .BTF_ids has
> > > +			 * Elf_Type = ELF_T_BYTE, and so libelf returns data buffer in
> > > +			 * the target endiannes. We repeat this on dump.
> > > +			 */
> > > +			if (obj->efile.encoding != ELFDATANATIVE) {
> > > +				pr_debug("bswap_32 .BTF_ids data from target to host endianness\n");
> > > +				bswap_32_data(data->d_buf, data->d_size);
> > > +			}
> > >  			obj->efile.idlist       = data;
> > >  			obj->efile.idlist_shndx = idx;
> > >  			obj->efile.idlist_addr  = sh.sh_addr;
> > > -		} else if (!strcmp(name, BTF_BASE_ELF_SEC)) {
> > > -			/* If a .BTF.base section is found, do not resolve
> > > -			 * BTF ids relative to vmlinux; resolve relative
> > > -			 * to the .BTF.base section instead.  btf__parse_split()
> > > -			 * will take care of this once the base BTF it is
> > > -			 * passed is NULL.
> > > -			 */
> > > -			obj->base_btf_path = NULL;
> > >  		}
> > > -
> > > -		if (compressed_section_fix(elf, scn, &sh))
> > > -			return -1;
> > >  	}
> > >  
> > >  	return 0;
> > > @@ -545,6 +521,13 @@ static int symbols_collect(struct object *obj)
> > >  	return 0;
> > >  }
> > >  
> > > +static inline bool is_envvar_set(const char *var_name)
> > > +{
> > > +	const char *value = getenv(var_name);
> > > +
> > > +	return value && value[0] != '\0';
> > > +}
> > > +
> > >  static int load_btf(struct object *obj)
> > >  {
> > >  	struct btf *base_btf = NULL, *btf = NULL;
> > > @@ -571,6 +554,20 @@ static int load_btf(struct object *obj)
> > >  	obj->base_btf = base_btf;
> > >  	obj->btf = btf;
> > >  
> > > +	if (obj->base_btf && is_envvar_set("KBUILD_EXTMOD")) {
> > 
> > This is a bit ugly, maybe use a dedicated parameter instead of
> > checking environment variable?
> 
> Disagree. I intentionally tried to avoid adding options to
> resolve_btfids, because it's not intendend for general CLI usage (as
> opposed to pahole, for example). IMO the interface should be as simple
> as possible.
> 
> If we add an option, we still have to check for the env variable
> somewhere, and then pass the argument through. Why? Just checking an
> env var when it matters is simpler.
> 
> I don't think we want or expect resolve_btfids to run outside of the
> kernel or selftests build.

This comes to personal opinion, of-course.
So, in my personal opinion, obfuscating a command line tool interface
with it being parameterized by both environment variables and command
line parameters is rarely justified.  In this particular case it will
only make life a tad harder for someone debugging resolve_btfids by
copy-pasting command from make output.

Hence, I find this piece of code ugly.

[...]

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ