Files
linux-stable-mirror/scripts/package/kernel.spec
T
Yafang ShaoandNathan Chancellor e5a259d988 kbuild: rpm-pkg: Preserve BTF sections in kernel modules during debuginfo stripping
After switching to the kernel's default package scripts for our local
kernel RPM builds, we noticed that module BTF entries were missing:

  $ ls /sys/kernel/btf/
  vmlinux    <<<< only vmlinux, no module BTF

Root cause: find-debuginfo.sh (from the debugedit package) prefers
eu-strip over strip when elfutils is installed, which is the common
case on RHEL 9. eu-strip removes non-allocated ELF sections, including
the .BTF section that contains BPF Type Format information for kernel
modules. Without .BTF, BPF tools (bpftool, bcc, bpftrace) cannot resolve
kernel types at runtime, and /sys/kernel/btf/<module> entries are not
created when modules are loaded.

Additionally, since commit 8646db2389 ("libbpf,bpf: Share BTF
relocate-related code with kernel"), modules contain a .BTF.base section
that maps distilled type IDs to vmlinux types. If .BTF.base is stripped,
btf_parse_module() falls back to vmlinux BTF directly, causing type ID
mismatches and rejecting the module's BTF entirely.

Fix by passing --keep-section .BTF and --keep-section .BTF.base via
_find_debuginfo_opts, which adds -K .BTF and -K .BTF.base to the
eu-strip/strip command, preserving both sections while allowing normal
debuginfo extraction to proceed.

After this change, all module BTF files are properly generated:

  $ ls /sys/kernel/btf/
  aesni_intel         drm                 i2c_i801            mfd_core
  ahci                drm_client_lib      i2c_mux             net_failover
  backlight           drm_kms_helper      i2c_smbus           pcspkr
  ccp                 drm_shmem_helper    input_leds          qemu_fw_cfg
  dm_log              failover            intel_rapl_common   sch_fq_codel
  dm_mirror           fat                 intel_rapl_msr      serio_raw
  dm_mod              fuse                irqbypass           sunrpc
  dm_region_hash      gf128mul            iTCO_wdt            vfat
  virtio_balloon      virtio_console      virtio_dma_buf      virtio_gpu
  virtio_net          virtio_rng          virtio_blk          vmlinux
  xfs

Suggested-by: Nathan Chancellor <nathan@kernel.org>
Signed-off-by: Yafang Shao <laoar.shao@gmail.com>
Cc: Alan Maguire <alan.maguire@oracle.com>
Link: https://patch.msgid.link/20260728024950.44946-1-laoar.shao@gmail.com
Signed-off-by: Nathan Chancellor <nathan@kernel.org>
2026-07-29 16:21:42 -07:00

227 lines
7.8 KiB
RPMSpec

# _arch is undefined if /usr/lib/rpm/platform/*/macros was not included.
%{!?_arch: %define _arch dummy}
%{!?make: %define make make}
%define makeflags %{?_smp_mflags} ARCH=%{ARCH}
Name: kernel
Summary: The Linux Kernel
Version: %(echo %{KERNELRELEASE} | sed -e 's/-/_/g')
Release: %{pkg_release}%{?dist}
License: GPL
Group: System Environment/Kernel
Vendor: The Linux Community
URL: https://www.kernel.org
Source0: linux.tar.gz
Source1: config
Source2: diff.patch
Provides: kernel-%{KERNELRELEASE}
BuildRequires: bc binutils bison dwarves
BuildRequires: (elfutils-devel or libdw-devel)
BuildRequires: (elfutils-libelf-devel or libelf-devel) flex
BuildRequires: gcc make openssl openssl-devel perl python3 rsync
%description
The Linux Kernel, the operating system core itself
%package headers
Summary: Header files for the Linux kernel for use by glibc
Group: Development/System
Obsoletes: kernel-headers < %{version}
Provides: kernel-headers = %{version}
%description headers
Kernel-headers includes the C header files that specify the interface
between the Linux kernel and userspace libraries and programs. The
header files define structures and constants that are needed for
building most standard programs and are also needed for rebuilding the
glibc package.
%if %{with_devel}
%package devel
Summary: Development package for building kernel modules to match the %{version} kernel
Group: System Environment/Kernel
AutoReqProv: no
%description -n kernel-devel
This package provides kernel headers and makefiles sufficient to build modules
against the %{version} kernel package.
%endif
%if %{with_debuginfo_manual}
%package debuginfo
Summary: Debug information package for the Linux kernel
Group: Development/Debug
AutoReq: 0
AutoProv: 1
%description debuginfo
This package provides debug information for the kernel image and modules from the
%{version} package.
%define install_mod_strip 1
%endif
%if %{with_debuginfo_rpm}
# list of debuginfo-related options taken from distribution kernel.spec
# files
%undefine _include_minidebuginfo
%undefine _find_debuginfo_dwz_opts
%undefine _unique_build_ids
%undefine _unique_debug_names
%undefine _unique_debug_srcs
%undefine _debugsource_packages
%undefine _debuginfo_subpackages
# Preserve .BTF and .BTF.base sections in kernel modules during debuginfo
# stripping. find-debuginfo.sh uses eu-strip which removes non-allocated ELF
# sections like .BTF by default. .BTF.base is required for BTF distillation
# support; without it, module BTF validation fails.
%global with_keep_section %(%{__find_debuginfo} --help 2>&1 | grep -c keep-section)
%if %{with_keep_section}
%global _find_debuginfo_opts -r --keep-section .BTF --keep-section .BTF.base
%else
%global _find_debuginfo_opts -r
%endif
%global _missing_build_ids_terminate_build 1
%global _no_recompute_build_ids 1
%{debug_package}
# later, we make all modules executable so that find-debuginfo.sh strips
# them up. but they don't actually need to be executable, so remove the
# executable bit, taking care to do it _after_ find-debuginfo.sh has run
%define __spec_install_post \
%{?__debug_package:%{__debug_install_post}} \
%{__arch_install_post} \
%{__os_install_post} \
find %{buildroot}/lib/modules/%{KERNELRELEASE} -name "*.ko" -type f \\\
| xargs --no-run-if-empty chmod u-x
%else
%define __spec_install_post /usr/lib/rpm/brp-compress || :
%endif
# some (but not all) versions of rpmbuild emit %%debug_package with
# %%install. since we've already emitted it manually, that would cause
# a package redefinition error. ensure that doesn't happen
%define debug_package %{nil}
%prep
%setup -q -n linux
cp %{SOURCE1} .config
patch -p1 < %{SOURCE2}
%build
%{make} %{makeflags} KERNELRELEASE=%{KERNELRELEASE} KBUILD_BUILD_VERSION=%{release}
%install
mkdir -p %{buildroot}/lib/modules/%{KERNELRELEASE}
cp $(%{make} %{makeflags} -s image_name) %{buildroot}/lib/modules/%{KERNELRELEASE}/vmlinuz
# DEPMOD=true makes depmod no-op. We do not package depmod-generated files.
%{make} %{makeflags} INSTALL_MOD_PATH=%{buildroot} %{?install_mod_strip:INSTALL_MOD_STRIP=1} DEPMOD=true modules_install
%{make} %{makeflags} INSTALL_HDR_PATH=%{buildroot}/usr headers_install
cp System.map %{buildroot}/lib/modules/%{KERNELRELEASE}
cp .config %{buildroot}/lib/modules/%{KERNELRELEASE}/config
if %{make} %{makeflags} run-command KBUILD_RUN_COMMAND='test -d ${srctree}/arch/${SRCARCH}/boot/dts' 2>/dev/null; then
%{make} %{makeflags} INSTALL_DTBS_PATH=%{buildroot}/lib/modules/%{KERNELRELEASE}/dtb dtbs_install
fi
ln -fns /usr/src/kernels/%{KERNELRELEASE} %{buildroot}/lib/modules/%{KERNELRELEASE}/build
%if %{with_devel}
%{make} %{makeflags} run-command KBUILD_RUN_COMMAND='${srctree}/scripts/package/install-extmod-build %{buildroot}/usr/src/kernels/%{KERNELRELEASE}'
%endif
{
echo "/lib/modules/%{KERNELRELEASE}"
for x in alias alias.bin builtin.alias.bin builtin.bin dep dep.bin \
devname softdep symbols symbols.bin weakdep; do
echo "%ghost /lib/modules/%{KERNELRELEASE}/modules.${x}"
done
for x in System.map config vmlinuz; do
echo "%ghost /boot/${x}-%{KERNELRELEASE}"
done
if [ -d "%{buildroot}/lib/modules/%{KERNELRELEASE}/dtb" ];then
find "%{buildroot}/lib/modules/%{KERNELRELEASE}/dtb" -printf "%%%ghost /boot/dtb-%{KERNELRELEASE}/%%P\n"
fi
echo "%exclude /lib/modules/%{KERNELRELEASE}/build"
} > %{buildroot}/kernel.list
%if 0%{with_debuginfo_manual}%{with_debuginfo_rpm} > 0
# copying vmlinux directly to the debug directory means it will not get
# stripped (but its source paths will still be collected + fixed up)
mkdir -p %{buildroot}/usr/lib/debug/lib/modules/%{KERNELRELEASE}
cp vmlinux %{buildroot}/usr/lib/debug/lib/modules/%{KERNELRELEASE}
%endif
%if %{with_debuginfo_rpm}
# make modules executable so that find-debuginfo.sh strips them. this
# will be undone later in %%__spec_install_post
find %{buildroot}/lib/modules/%{KERNELRELEASE} -name "*.ko" -type f \
| xargs --no-run-if-empty chmod u+x
%endif
%if %{with_debuginfo_manual}
echo /usr/lib/debug/lib/modules/%{KERNELRELEASE}/vmlinux > %{buildroot}/debuginfo.list
while read -r mod; do
mod="${mod%.o}.ko"
dbg="%{buildroot}/usr/lib/debug/lib/modules/%{KERNELRELEASE}/kernel/${mod}"
buildid=$("${READELF:-readelf}" -n "${mod}" | sed -n 's@^.*Build ID: \(..\)\(.*\)@\1/\2@p')
link="%{buildroot}/usr/lib/debug/.build-id/${buildid}.debug"
mkdir -p "${dbg%/*}" "${link%/*}"
"${OBJCOPY:-objcopy}" --only-keep-debug "${mod}" "${dbg}"
ln -sf --relative "${dbg}" "${link}"
echo "${dbg#%{buildroot}}" >> %{buildroot}/debuginfo.list
echo "${link#%{buildroot}}" >> %{buildroot}/debuginfo.list
done < modules.order
%endif
%clean
rm -rf %{buildroot}
%if %{with_debuginfo_rpm}
rm -f debugfiles.list debuglinks.list debugsourcefiles.list debugsources.list \
elfbins.list
%endif
%post
if [ -x /usr/bin/kernel-install ]; then
/usr/bin/kernel-install add %{KERNELRELEASE} /lib/modules/%{KERNELRELEASE}/vmlinuz
fi
for file in vmlinuz System.map config; do
if ! cmp --silent "/lib/modules/%{KERNELRELEASE}/${file}" "/boot/${file}-%{KERNELRELEASE}"; then
cp "/lib/modules/%{KERNELRELEASE}/${file}" "/boot/${file}-%{KERNELRELEASE}"
fi
done
if [ -d "/lib/modules/%{KERNELRELEASE}/dtb" ] && \
! diff -rq "/lib/modules/%{KERNELRELEASE}/dtb" "/boot/dtb-%{KERNELRELEASE}" >/dev/null 2>&1; then
rm -rf "/boot/dtb-%{KERNELRELEASE}"
cp -r "/lib/modules/%{KERNELRELEASE}/dtb" "/boot/dtb-%{KERNELRELEASE}"
fi
if [ ! -e "/lib/modules/%{KERNELRELEASE}/modules.dep" ]; then
/usr/sbin/depmod %{KERNELRELEASE}
fi
%preun
if [ -x /usr/bin/kernel-install ]; then
kernel-install remove %{KERNELRELEASE}
fi
%files -f %{buildroot}/kernel.list
%defattr (-, root, root)
%exclude /kernel.list
%files headers
%defattr (-, root, root)
/usr/include
%if %{with_devel}
%files devel
%defattr (-, root, root)
/usr/src/kernels/%{KERNELRELEASE}
/lib/modules/%{KERNELRELEASE}/build
%endif
%if %{with_debuginfo_manual}
%files -f %{buildroot}/debuginfo.list debuginfo
%defattr (-, root, root)
%exclude /debuginfo.list
%endif