Something went wrong. Try again.
Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148#!/bin/sh# 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 ;; esacdone
if [ $# -ne 1 ]; then usagefi
ELF_FILE="$1"shift
is_enabled() { grep -q "^$1=y" ${objtree}/include/config/auto.conf}
case "${KBUILD_VERBOSE}" in*1*) set -x ;;esac
gen_btf_data(){ btf1="${ELF_FILE}.BTF.1" ${PAHOLE} -J ${PAHOLE_FLAGS} \ ${BTF_BASE:+--btf_base ${BTF_BASE}} \ --btf_encode_detached=${btf1} \ "${ELF_FILE}"
${RESOLVE_BTFIDS} ${RESOLVE_BTFIDS_FLAGS} \ ${BTF_BASE:+--btf_base ${BTF_BASE}} \ --btf ${btf1} "${ELF_FILE}"}
gen_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 # deletes all symbols including __start_BTF and __stop_BTF, which will # be redefined in the linker script. 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}
# 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(){ ${OBJCOPY} --add-section .BTF=${ELF_FILE}.BTF ${ELF_FILE}
# a module might not have a .BTF_ids or .BTF.base section btf_base="${ELF_FILE}.BTF.base" if [ -f "${btf_base}" ]; then ${OBJCOPY} --add-section .BTF.base=${btf_base} ${ELF_FILE} fi btf_ids="${ELF_FILE}.BTF_ids" if [ -f "${btf_ids}" ]; then ${RESOLVE_BTFIDS} --patch_btfids ${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}" invmlinux) gen_btf_o ;;module) embed_btf_data ;;esac
exit 0