Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
1#!/bin/sh
2# SPDX-License-Identifier: GPL-2.0
3# Copyright (c) 2025 Meta Platforms, Inc. and affiliates.
4#
5# This script generates BTF data for the provided ELF file.
6#
7# Kernel BTF generation involves these conceptual steps:
8# 1. pahole generates BTF from DWARF data
9# 2. resolve_btfids applies kernel-specific btf2btf
10# transformations and computes data for .BTF_ids section
11# 3. the result gets linked/objcopied into the target binary
12#
13# How step (3) should be done differs between vmlinux, and
14# kernel modules, which is the primary reason for the existence
15# of this script.
16#
17# For modules the script expects vmlinux passed in as --btf_base.
18# Generated .BTF, .BTF.base and .BTF_ids sections become embedded
19# into the input ELF file with objcopy.
20#
21# For vmlinux the input file remains unchanged and two files are produced:
22# - ${1}.btf.o ready for linking into vmlinux
23# - ${1}.BTF_ids with .BTF_ids data blob
24# This output is consumed by scripts/link-vmlinux.sh
25
26set -e
27
28usage()
29{
30 echo "Usage: $0 [--btf_base <file>] <target ELF file>"
31 exit 1
32}
33
34BTF_BASE=""
35
36while [ $# -gt 0 ]; do
37 case "$1" in
38 --btf_base)
39 BTF_BASE="$2"
40 shift 2
41 ;;
42 -*)
43 echo "Unknown option: $1" >&2
44 usage
45 ;;
46 *)
47 break
48 ;;
49 esac
50done
51
52if [ $# -ne 1 ]; then
53 usage
54fi
55
56ELF_FILE="$1"
57shift
58
59is_enabled() {
60 grep -q "^$1=y" ${objtree}/include/config/auto.conf
61}
62
63case "${KBUILD_VERBOSE}" in
64*1*)
65 set -x
66 ;;
67esac
68
69gen_btf_data()
70{
71 btf1="${ELF_FILE}.BTF.1"
72 ${PAHOLE} -J ${PAHOLE_FLAGS} \
73 ${BTF_BASE:+--btf_base ${BTF_BASE}} \
74 --btf_encode_detached=${btf1} \
75 "${ELF_FILE}"
76
77 ${RESOLVE_BTFIDS} ${RESOLVE_BTFIDS_FLAGS} \
78 ${BTF_BASE:+--btf_base ${BTF_BASE}} \
79 --btf ${btf1} "${ELF_FILE}"
80}
81
82gen_btf_o()
83{
84 btf_data=${ELF_FILE}.btf.o
85
86 # Create ${btf_data} which contains just .BTF section but no symbols. Add
87 # SHF_ALLOC because .BTF will be part of the vmlinux image. --strip-all
88 # deletes all symbols including __start_BTF and __stop_BTF, which will
89 # be redefined in the linker script.
90 echo "" | ${CC} ${CLANG_FLAGS} ${KBUILD_CPPFLAGS} ${KBUILD_CFLAGS} -fno-lto -c -x c -o ${btf_data} -
91 ${OBJCOPY} --add-section .BTF=${ELF_FILE}.BTF \
92 --set-section-flags .BTF=alloc,readonly ${btf_data}
93 ${OBJCOPY} --only-section=.BTF --strip-all ${btf_data}
94
95 # Change e_type to ET_REL so that it can be used to link final vmlinux.
96 # GNU ld 2.35+ and lld do not allow an ET_EXEC input.
97 if is_enabled CONFIG_CPU_BIG_ENDIAN; then
98 et_rel='\0\1'
99 else
100 et_rel='\1\0'
101 fi
102 printf "${et_rel}" | dd of="${btf_data}" conv=notrunc bs=1 seek=16 status=none
103}
104
105embed_btf_data()
106{
107 ${OBJCOPY} --add-section .BTF=${ELF_FILE}.BTF ${ELF_FILE}
108
109 # a module might not have a .BTF_ids or .BTF.base section
110 btf_base="${ELF_FILE}.BTF.base"
111 if [ -f "${btf_base}" ]; then
112 ${OBJCOPY} --add-section .BTF.base=${btf_base} ${ELF_FILE}
113 fi
114 btf_ids="${ELF_FILE}.BTF_ids"
115 if [ -f "${btf_ids}" ]; then
116 ${RESOLVE_BTFIDS} --patch_btfids ${btf_ids} ${ELF_FILE}
117 fi
118}
119
120cleanup()
121{
122 rm -f "${ELF_FILE}.BTF.1"
123 rm -f "${ELF_FILE}.BTF"
124 if [ "${BTFGEN_MODE}" = "module" ]; then
125 rm -f "${ELF_FILE}.BTF.base"
126 rm -f "${ELF_FILE}.BTF_ids"
127 fi
128}
129trap cleanup EXIT
130
131BTFGEN_MODE="vmlinux"
132if [ -n "${BTF_BASE}" ]; then
133 BTFGEN_MODE="module"
134fi
135
136gen_btf_data
137
138case "${BTFGEN_MODE}" in
139vmlinux)
140 gen_btf_o
141 ;;
142module)
143 embed_btf_data
144 ;;
145esac
146
147exit 0