From 903922cfa0e60573234ff895974c23a000035258 Mon Sep 17 00:00:00 2001 From: Ihor Solodrai Date: Fri, 19 Dec 2025 10:18:23 -0800 Subject: lib/Kconfig.debug: Set the minimum required pahole version to v1.22 Subsequent patches in the series change vmlinux linking scripts to unconditionally pass --btf_encode_detached to pahole, which was introduced in v1.22 [1][2]. This change allows to remove PAHOLE_HAS_SPLIT_BTF Kconfig option and other checks of older pahole versions. [1] https://github.com/acmel/dwarves/releases/tag/v1.22 [2] https://lore.kernel.org/bpf/cbafbf4e-9073-4383-8ee6-1353f9e5869c@oracle.com/ Signed-off-by: Ihor Solodrai Signed-off-by: Andrii Nakryiko Tested-by: Alan Maguire Acked-by: Eduard Zingerman Acked-by: Nicolas Schier Link: https://lore.kernel.org/bpf/20251219181825.1289460-1-ihor.solodrai@linux.dev --- scripts/Makefile.btf | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) (limited to 'scripts') diff --git a/scripts/Makefile.btf b/scripts/Makefile.btf index db76335dd917..840a55de42da 100644 --- a/scripts/Makefile.btf +++ b/scripts/Makefile.btf @@ -7,14 +7,7 @@ JOBS := $(patsubst -j%,%,$(filter -j%,$(MAKEFLAGS))) ifeq ($(call test-le, $(pahole-ver), 125),y) -# pahole 1.18 through 1.21 can't handle zero-sized per-CPU vars -ifeq ($(call test-le, $(pahole-ver), 121),y) -pahole-flags-$(call test-ge, $(pahole-ver), 118) += --skip_encoding_btf_vars -endif - -pahole-flags-$(call test-ge, $(pahole-ver), 121) += --btf_gen_floats - -pahole-flags-$(call test-ge, $(pahole-ver), 122) += -j$(JOBS) +pahole-flags-y += --btf_gen_floats -j$(JOBS) pahole-flags-$(call test-ge, $(pahole-ver), 125) += --skip_encoding_btf_inconsistent_proto --btf_gen_optimized -- cgit v1.2.3 From 522397d05e7d4a7c30b91841492360336b24f833 Mon Sep 17 00:00:00 2001 From: Ihor Solodrai Date: Fri, 19 Dec 2025 10:18:25 -0800 Subject: resolve_btfids: Change in-place update with raw binary output 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. Change 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}.BTF_ids with .BTF_ids section data if it existed in ${1} * ${1}.BTF.base with .BTF.base section data for out-of-tree modules The execution of resolve_btfids and consumption of its output is orchestrated by scripts/gen-btf.sh introduced in this patch. The motivation for emitting binary data is that it allows simplifying resolve_btfids implementation by delegating ELF update to the $OBJCOPY tool [1], which is already widely used across the codebase. 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. The patch doesn't change this approach, only the implementation is a little different. Before this patch it worked as follows: * pahole consumed .tmp_vmlinux1 [2] and added .BTF section with llvm-objcopy [3] to it * then everything except the .BTF section was stripped from .tmp_vmlinux1 into a .tmp_vmlinux1.bpf.o object [2], later linked into vmlinux * resolve_btfids was executed later on vmlinux.unstripped [4], 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 kernel modules, creating a special .bpf.o file is not necessary, and so embedding of sections data produced by resolve_btfids is straightforward with objcopy. With this patch an ELF file becomes effectively read-only within resolve_btfids, which allows deleting elf_update() call and satellite code (like compressed_section_fix [5]). Endianness handling of .BTF_ids data is also changed. Previously the "flags" part of the section was bswapped in sets_patch() [6], 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://lore.kernel.org/bpf/131b4190-9c49-4f79-a99d-c00fac97fa44@linux.dev/ [2] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/scripts/link-vmlinux.sh?h=v6.18#n110 [3] https://git.kernel.org/pub/scm/devel/pahole/pahole.git/tree/btf_encoder.c?h=v1.31#n1803 [4] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/scripts/link-vmlinux.sh?h=v6.18#n284 [5] https://lore.kernel.org/bpf/20200819092342.259004-1-jolsa@kernel.org/ [6] https://lore.kernel.org/bpf/cover.1707223196.git.vmalik@redhat.com/ Signed-off-by: Ihor Solodrai Signed-off-by: Andrii Nakryiko Tested-by: Alan Maguire Acked-by: Eduard Zingerman Link: https://lore.kernel.org/bpf/20251219181825.1289460-3-ihor.solodrai@linux.dev --- scripts/Makefile.btf | 12 ++-- scripts/Makefile.modfinal | 5 +- scripts/Makefile.vmlinux | 2 +- scripts/gen-btf.sh | 157 ++++++++++++++++++++++++++++++++++++++++++++++ scripts/link-vmlinux.sh | 42 ++----------- 5 files changed, 173 insertions(+), 45 deletions(-) create mode 100755 scripts/gen-btf.sh (limited to 'scripts') diff --git a/scripts/Makefile.btf b/scripts/Makefile.btf index 840a55de42da..562a04b40e06 100644 --- a/scripts/Makefile.btf +++ b/scripts/Makefile.btf @@ -18,13 +18,15 @@ pahole-flags-$(call test-ge, $(pahole-ver), 126) = -j$(JOBS) --btf_features=enc pahole-flags-$(call test-ge, $(pahole-ver), 130) += --btf_features=attributes -ifneq ($(KBUILD_EXTMOD),) -module-pahole-flags-$(call test-ge, $(pahole-ver), 128) += --btf_features=distilled_base -endif - endif pahole-flags-$(CONFIG_PAHOLE_HAS_LANG_EXCLUDE) += --lang_exclude=rust export PAHOLE_FLAGS := $(pahole-flags-y) -export MODULE_PAHOLE_FLAGS := $(module-pahole-flags-y) + +resolve-btfids-flags-y := +resolve-btfids-flags-$(CONFIG_WERROR) += --fatal_warnings +resolve-btfids-flags-$(if $(KBUILD_EXTMOD),y) += --distill_base +resolve-btfids-flags-$(if $(KBUILD_VERBOSE),y) += --verbose + +export RESOLVE_BTFIDS_FLAGS := $(resolve-btfids-flags-y) diff --git a/scripts/Makefile.modfinal b/scripts/Makefile.modfinal index 149e12ff5700..422c56dc878e 100644 --- a/scripts/Makefile.modfinal +++ b/scripts/Makefile.modfinal @@ -42,9 +42,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/Makefile.vmlinux b/scripts/Makefile.vmlinux index cd788cac9d91..20a988f4fe0c 100644 --- a/scripts/Makefile.vmlinux +++ b/scripts/Makefile.vmlinux @@ -71,7 +71,7 @@ targets += vmlinux.unstripped .vmlinux.export.o vmlinux.unstripped: scripts/link-vmlinux.sh vmlinux.o .vmlinux.export.o $(KBUILD_LDS) FORCE +$(call if_changed_dep,link_vmlinux) ifdef CONFIG_DEBUG_INFO_BTF -vmlinux.unstripped: $(RESOLVE_BTFIDS) +vmlinux.unstripped: $(RESOLVE_BTFIDS) $(srctree)/scripts/gen-btf.sh endif ifdef CONFIG_BUILDTIME_TABLE_SORT diff --git a/scripts/gen-btf.sh b/scripts/gen-btf.sh new file mode 100755 index 000000000000..06c6d8becaa2 --- /dev/null +++ b/scripts/gen-btf.sh @@ -0,0 +1,157 @@ +#!/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 ] " + 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 + + +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} ${RESOLVE_BTFIDS_FLAGS} \ + ${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} ${CLANG_FLAGS} -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}.BTF" + ${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}.BTF.base" + 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}.BTF.base" + 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 4ab44c73da4d..e2207e612ac3 100755 --- a/scripts/link-vmlinux.sh +++ b/scripts/link-vmlinux.sh @@ -106,34 +106,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() { @@ -205,6 +177,7 @@ if is_enabled CONFIG_ARCH_WANTS_PRE_LINK_VMLINUX; then fi btf_vmlinux_bin_o= +btfids_vmlinux= kallsymso= strip_debug= generate_map= @@ -232,11 +205,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 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 @@ -289,14 +264,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 mksysmap "${VMLINUX}" System.map -- cgit v1.2.3 From 600605853f87a4b1c3530a63f78a3541633402b0 Mon Sep 17 00:00:00 2001 From: Ihor Solodrai Date: Mon, 29 Dec 2025 12:28:23 -0800 Subject: scripts/gen-btf.sh: Fix .btf.o generation when compiling for RISCV gen-btf.sh emits a .btf.o file with BTF sections to be linked into vmlinux in link-vmlinux.sh This .btf.o file is created by compiling an emptystring with ${CC}, and then adding BTF sections into it with ${OBJCOPY}. To ensure the .btf.o is linkable when cross-compiling with LLVM, we have to also pass ${KBUILD_FLAGS}, which in particular control the target word size. Reported-by: kernel test robot Closes: https://lore.kernel.org/oe-kbuild-all/202512240559.2M06DSX7-lkp@intel.com/ Signed-off-by: Ihor Solodrai Link: https://lore.kernel.org/r/20251229202823.569619-1-ihor.solodrai@linux.dev Signed-off-by: Alexei Starovoitov --- scripts/gen-btf.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/gen-btf.sh b/scripts/gen-btf.sh index 06c6d8becaa2..12244dbe097c 100755 --- a/scripts/gen-btf.sh +++ b/scripts/gen-btf.sh @@ -96,7 +96,7 @@ gen_btf_o() # deletes all symbols including __start_BTF and __stop_BTF, which will # be redefined in the linker script. info OBJCOPY "${btf_data}" - echo "" | ${CC} ${CLANG_FLAGS} -c -x c -o ${btf_data} - + echo "" | ${CC} ${CLANG_FLAGS} ${KBUILD_CFLAGS} -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} -- cgit v1.2.3 From 1a8fa7faf4890d201aad4f5d4943f74d840cd0ba Mon Sep 17 00:00:00 2001 From: Ihor Solodrai Date: Tue, 30 Dec 2025 17:25:57 -0800 Subject: resolve_btfids: Implement --patch_btfids Recent changes in BTF generation [1] rely on ${OBJCOPY} command to update .BTF_ids section data in target ELF files. This exposed a bug in llvm-objcopy --update-section code path, that may lead to corruption of a target ELF file. Specifically, because of the bug st_shndx of some symbols may be (incorrectly) set to 0xffff (SHN_XINDEX) [2][3]. While there is a pending fix for LLVM, it'll take some time before it lands (likely in 22.x). And the kernel build must keep working with older LLVM toolchains in the foreseeable future. Using GNU objcopy for .BTF_ids update would work, but it would require changes to LLVM-based build process, likely breaking existing build environments as discussed in [2]. To work around llvm-objcopy bug, implement --patch_btfids code path in resolve_btfids as a drop-in replacement for: ${OBJCOPY} --update-section .BTF_ids=${btf_ids} ${elf} Which works specifically for .BTF_ids section: ${RESOLVE_BTFIDS} --patch_btfids ${btf_ids} ${elf} This feature in resolve_btfids can be removed at some point in the future, when llvm-objcopy with a relevant bugfix becomes common. [1] https://lore.kernel.org/bpf/20251219181321.1283664-1-ihor.solodrai@linux.dev/ [2] https://lore.kernel.org/bpf/20251224005752.201911-1-ihor.solodrai@linux.dev/ [3] https://github.com/llvm/llvm-project/issues/168060#issuecomment-3533552952 Signed-off-by: Ihor Solodrai Link: https://lore.kernel.org/r/20251231012558.1699758-1-ihor.solodrai@linux.dev Signed-off-by: Alexei Starovoitov --- scripts/gen-btf.sh | 2 +- scripts/link-vmlinux.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/gen-btf.sh b/scripts/gen-btf.sh index 12244dbe097c..0aec86615416 100755 --- a/scripts/gen-btf.sh +++ b/scripts/gen-btf.sh @@ -123,7 +123,7 @@ embed_btf_data() fi local btf_ids="${ELF_FILE}.BTF_ids" if [ -f "${btf_ids}" ]; then - ${OBJCOPY} --update-section .BTF_ids=${btf_ids} ${ELF_FILE} + ${RESOLVE_BTFIDS} --patch_btfids ${btf_ids} ${ELF_FILE} fi } diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh index e2207e612ac3..1915adf3249b 100755 --- a/scripts/link-vmlinux.sh +++ b/scripts/link-vmlinux.sh @@ -266,7 +266,7 @@ vmlinux_link "${VMLINUX}" if is_enabled CONFIG_DEBUG_INFO_BTF; then info OBJCOPY ${btfids_vmlinux} - ${OBJCOPY} --update-section .BTF_ids=${btfids_vmlinux} ${VMLINUX} + ${RESOLVE_BTFIDS} --patch_btfids ${btfids_vmlinux} ${VMLINUX} fi mksysmap "${VMLINUX}" System.map -- cgit v1.2.3 From 453dece55bb1cc6812314497a1c5ecc0513457ed Mon Sep 17 00:00:00 2001 From: Ihor Solodrai Date: Wed, 31 Dec 2025 10:39:29 -0800 Subject: scripts/gen-btf.sh: Reduce log verbosity Remove info messages from gen-btf.sh, as they are unnecessarily detailed and sometimes inaccurate [1]. Verbose log can be produced by passing V=1 to make, which will set -x for the shell. [1] https://lore.kernel.org/bpf/CAADnVQ+biTSDaNtoL=ct9XtBJiXYMUqGYLqu604C3D8N+8YH9A@mail.gmail.com/ Suggested-by: Alexei Starovoitov Signed-off-by: Ihor Solodrai Link: https://lore.kernel.org/r/20251231183929.65668-1-ihor.solodrai@linux.dev Signed-off-by: Alexei Starovoitov --- scripts/gen-btf.sh | 10 ---------- scripts/link-vmlinux.sh | 3 ++- 2 files changed, 2 insertions(+), 11 deletions(-) (limited to 'scripts') diff --git a/scripts/gen-btf.sh b/scripts/gen-btf.sh index 0aec86615416..d6457661b9b6 100755 --- a/scripts/gen-btf.sh +++ b/scripts/gen-btf.sh @@ -60,28 +60,20 @@ 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 - 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} ${RESOLVE_BTFIDS_FLAGS} \ ${BTF_BASE:+--btf_base ${BTF_BASE}} \ --btf ${btf1} "${ELF_FILE}" @@ -95,7 +87,6 @@ gen_btf_o() # 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} ${CLANG_FLAGS} ${KBUILD_CFLAGS} -c -x c -o ${btf_data} - ${OBJCOPY} --add-section .BTF=${ELF_FILE}.BTF \ --set-section-flags .BTF=alloc,readonly ${btf_data} @@ -113,7 +104,6 @@ gen_btf_o() embed_btf_data() { - info OBJCOPY "${ELF_FILE}.BTF" ${OBJCOPY} --add-section .BTF=${ELF_FILE}.BTF ${ELF_FILE} # a module might not have a .BTF_ids or .BTF.base section diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh index 1915adf3249b..08cd8e25c65c 100755 --- a/scripts/link-vmlinux.sh +++ b/scripts/link-vmlinux.sh @@ -205,6 +205,7 @@ if is_enabled CONFIG_KALLSYMS || is_enabled CONFIG_DEBUG_INFO_BTF; then fi if is_enabled CONFIG_DEBUG_INFO_BTF; then + info BTF .tmp_vmlinux1 if ! ${srctree}/scripts/gen-btf.sh .tmp_vmlinux1; then echo >&2 "Failed to generate BTF for vmlinux" echo >&2 "Try to disable CONFIG_DEBUG_INFO_BTF" @@ -265,7 +266,7 @@ fi vmlinux_link "${VMLINUX}" if is_enabled CONFIG_DEBUG_INFO_BTF; then - info OBJCOPY ${btfids_vmlinux} + info BTFIDS ${VMLINUX} ${RESOLVE_BTFIDS} --patch_btfids ${btfids_vmlinux} ${VMLINUX} fi -- cgit v1.2.3 From 2421649778dca8fe6e7b166905e97278aa0fdf58 Mon Sep 17 00:00:00 2001 From: Nathan Chancellor Date: Tue, 6 Jan 2026 15:44:20 -0700 Subject: scripts/gen-btf.sh: Ensure initial object in gen_btf_o is ELF with correct endianness After commit 600605853f87 ("scripts/gen-btf.sh: Fix .btf.o generation when compiling for RISCV"), there is an error from llvm-objcopy when CONFIG_LTO_CLANG is enabled: llvm-objcopy: error: '.tmp_vmlinux1.btf.o': The file was not recognized as a valid object file Failed to generate BTF for vmlinux KBUILD_CFLAGS includes CC_FLAGS_LTO, which makes clang emit an LLVM IR object, rather than an ELF one as expected by llvm-objcopy. Most areas of the kernel deal with this by filtering out CC_FLAGS_LTO from KBUILD_CFLAGS for the particular object or directory but this is not so easy to do in bash. Just include '-fno-lto' after KBUILD_CFLAGS to ensure an ELF object is consistently created as the initial .o file. Additionally, while there is no reported or discovered bug yet, the absence of KBUILD_CPPFLAGS from this command could result in incorrect endianness because KBUILD_CPPFLAGS typically contains '-mbig-endian' and '-mlittle-endian' so that biendian toolchains can be used. Include it in this ${CC} command to hopefully limit necessary changes to this command for the foreseeable future. Fixes: 600605853f87 ("scripts/gen-btf.sh: Fix .btf.o generation when compiling for RISCV") Signed-off-by: Nathan Chancellor Acked-by: Ihor Solodrai Link: https://lore.kernel.org/r/20260106-fix-gen-btf-sh-lto-v2-1-01d3e1c241c4@kernel.org Signed-off-by: Alexei Starovoitov --- scripts/gen-btf.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/gen-btf.sh b/scripts/gen-btf.sh index d6457661b9b6..be21ccee3487 100755 --- a/scripts/gen-btf.sh +++ b/scripts/gen-btf.sh @@ -87,7 +87,7 @@ gen_btf_o() # 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. - echo "" | ${CC} ${CLANG_FLAGS} ${KBUILD_CFLAGS} -c -x c -o ${btf_data} - + echo "" | ${CC} ${CLANG_FLAGS} ${KBUILD_CPPFLAGS} ${KBUILD_CFLAGS} -fno-lto -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} -- cgit v1.2.3 From 26ad5d6e763070aa146d86b941884b11eb1ac0aa Mon Sep 17 00:00:00 2001 From: Ihor Solodrai Date: Wed, 21 Jan 2026 10:16:17 -0800 Subject: scripts/gen-btf.sh: Use CONFIG_SHELL for execution MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit According to the docs [1], kernel build scripts should be executed via CONFIG_SHELL, which is sh by default. Fixup gen-btf.sh to be runnable with sh, and use CONFIG_SHELL at every invocation site. See relevant discussion for context [2]. [1] https://docs.kernel.org/kbuild/makefiles.html#script-invocation [2] https://lore.kernel.org/bpf/CAADnVQ+dxmSNoJAGb6xV89ffUCKXe5CJXovXZt22nv5iYFV5mw@mail.gmail.com/ Signed-off-by: Ihor Solodrai Tested-by: Gary Guo Reported-by: Gary Guo Suggested-by: Thomas Weißschuh Fixes: 522397d05e7d ("resolve_btfids: Change in-place update with raw binary output") Link: https://lore.kernel.org/r/20260121181617.820300-1-ihor.solodrai@linux.dev Signed-off-by: Alexei Starovoitov --- scripts/Makefile.modfinal | 2 +- scripts/gen-btf.sh | 8 ++++---- scripts/link-vmlinux.sh | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) (limited to 'scripts') diff --git a/scripts/Makefile.modfinal b/scripts/Makefile.modfinal index 422c56dc878e..adcbcde16a07 100644 --- a/scripts/Makefile.modfinal +++ b/scripts/Makefile.modfinal @@ -43,7 +43,7 @@ quiet_cmd_btf_ko = BTF [M] $@ if [ ! -f $(objtree)/vmlinux ]; then \ printf "Skipping BTF generation for %s due to unavailability of vmlinux\n" $@ 1>&2; \ else \ - $(srctree)/scripts/gen-btf.sh --btf_base $(objtree)/vmlinux $@; \ + $(CONFIG_SHELL) $(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 index be21ccee3487..8ca96eb10a69 100755 --- a/scripts/gen-btf.sh +++ b/scripts/gen-btf.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/bin/sh # SPDX-License-Identifier: GPL-2.0 # Copyright (c) 2025 Meta Platforms, Inc. and affiliates. # @@ -81,7 +81,7 @@ gen_btf_data() gen_btf_o() { - local btf_data=${ELF_FILE}.btf.o + 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 @@ -107,11 +107,11 @@ embed_btf_data() ${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}.BTF.base" + btf_base="${ELF_FILE}.BTF.base" if [ -f "${btf_base}" ]; then ${OBJCOPY} --add-section .BTF.base=${btf_base} ${ELF_FILE} fi - local btf_ids="${ELF_FILE}.BTF_ids" + btf_ids="${ELF_FILE}.BTF_ids" if [ -f "${btf_ids}" ]; then ${RESOLVE_BTFIDS} --patch_btfids ${btf_ids} ${ELF_FILE} fi diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh index 08cd8e25c65c..16d6a048e07c 100755 --- a/scripts/link-vmlinux.sh +++ b/scripts/link-vmlinux.sh @@ -206,7 +206,7 @@ fi if is_enabled CONFIG_DEBUG_INFO_BTF; then info BTF .tmp_vmlinux1 - if ! ${srctree}/scripts/gen-btf.sh .tmp_vmlinux1; then + if ! ${CONFIG_SHELL} ${srctree}/scripts/gen-btf.sh .tmp_vmlinux1; then echo >&2 "Failed to generate BTF for vmlinux" echo >&2 "Try to disable CONFIG_DEBUG_INFO_BTF" exit 1 -- cgit v1.2.3