Alexey Sheplyakov
2b153b6f00
Linux kernel supports the direct loading of compressed modules (via finit_module system call) since version 5.15. However decompression options are less flexible (and are set at the compile time). In particular kernel can read lzma archives only with a dictionary size exactly 1 MiB, and crc32 checksum. kmod started to make use of direct module loading since version 31. However kmod does not fall back to decompressing in the userspace if the kernel compressed modules, which causes serious troubles (boot failures, some devices not working, etc). To avoid the problem teach process-debuginfo.in to re-compress kernel modules correctly (crc32 checksum, 1 MiB dictionary) so the kernel can load them directly. Link: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=fbf5892df21a8ccfcb2fda0fd65bc3169c89ed28 Reviewed-by: Vitaly Chikunov <vt@altlinux.org>
142 lines
3.7 KiB
Bash
Executable File
142 lines
3.7 KiB
Bash
Executable File
#!/bin/sh -efu
|
|
#
|
|
# Process single file for debuginfo business.
|
|
# (Will be run multiple instances in parallel.)
|
|
#
|
|
# Copyright (c) 2020 Vitaly Chikunov <vt@altlinux.org>. Based on brp-debuginfo
|
|
# written by Alexey Tourbin <at@altlinux.org>. Based on find-debuginfo.sh
|
|
# by Jeff Johnson <jbj@rpm5.org> and Roland McGrath <roland@redhat.com>.
|
|
# License: GPLv2+.
|
|
|
|
. @RPMCONFIGDIR@/functions
|
|
ValidateBuildRoot
|
|
|
|
cd "$RPM_BUILD_ROOT"
|
|
|
|
mkdir -p .tmp
|
|
|
|
f=$1
|
|
rezip=
|
|
elfcompress=
|
|
strip_rel=
|
|
strip_btf='--keep-section=.BTF'
|
|
strip='--strip-all'
|
|
|
|
if [ -z "${f#./lib/modules/*.ko}" ]; then
|
|
elfcompress=yes
|
|
strip_rel="--reloc-debug-sections"
|
|
elif [ -z "${f##./lib/modules/*.ko.*}" ]; then
|
|
ext=${f##*.}
|
|
unzip=
|
|
rezip=
|
|
case "$ext" in
|
|
gz)
|
|
unzip='gzip --force --decompress'
|
|
rezip='gzip --force --keep'
|
|
;;
|
|
xz)
|
|
unzip='xz --force --decompress'
|
|
rezip='xz --check=crc32 --lzma2=dict=1MiB --force --keep'
|
|
;;
|
|
zst)
|
|
unzip='zstd --quiet --force --rm --decompress'
|
|
rezip='zstd --quiet --force'
|
|
;;
|
|
esac
|
|
# Compressed module: uncompress it, and work with uncompressed one.
|
|
$unzip "$f"
|
|
f="${f%.*}"
|
|
elfcompress=yes
|
|
strip_rel="--reloc-debug-sections"
|
|
elif [ -z "${f##./boot/vmlinuz-*}" ]; then
|
|
# Compressed kernel: trigger extraction of vmlinux from the source.
|
|
kver=${f#./boot/vmlinuz-}
|
|
vmlinuxs=$(find "$RPM_BUILD_DIR" -depth -maxdepth 4 -type f -name vmlinux -print -quit)
|
|
vmlinuxd=./usr/lib/debug/lib/modules/$kver/vmlinux
|
|
|
|
if [ -f "$vmlinuxs" ]; then
|
|
install -pD -m644 "$vmlinuxs" "$vmlinuxd"
|
|
f=$vmlinuxd
|
|
strip=
|
|
else
|
|
Warning "vmlinux not found in $RPM_BUILD_DIR for -debuginfo"
|
|
exit
|
|
fi
|
|
else
|
|
# Non-kernel binaries
|
|
strip_btf=
|
|
fi
|
|
|
|
debugf=./usr/lib/debug${f#.}.debug
|
|
for pat in ${RPM_BRP_STRIP_DEBUG-}; do
|
|
if [ -z "${f##.$pat}" ]; then
|
|
strip='--strip-debug'
|
|
break
|
|
fi
|
|
done
|
|
for pat in ${RPM_BRP_STRIP_NONE-}; do
|
|
if [ -z "${f##.$pat}" ]; then
|
|
strip=
|
|
break
|
|
fi
|
|
done
|
|
|
|
timestamp=$(date --iso-8601=ns --reference="$f")
|
|
debugedit -b "$RPM_BUILD_DIR" -d /usr/src/debug -l .tmp/src.$$ "$f"
|
|
if [ ! -s .tmp/src.$$ ] && [ -x /usr/bin/eu-elfcompress ]; then
|
|
# debugedit has failed to extract sources list, possibly
|
|
# due to ELF compression - uncompress and try again.
|
|
LD_ORIGIN_PATH=/usr/bin eu-readelf -S "$f" > .tmp/sections.$$
|
|
if grep -q ' \.debug_info .* PROGBITS .*C' .tmp/sections.$$; then
|
|
# Have SHF_COMPRESSED flag.
|
|
zmode=zlib-gabi
|
|
elif grep -q ' \.zdebug_info .* PROGBITS ' .tmp/sections.$$; then
|
|
zmode=zlib-gnu
|
|
else
|
|
zmode=
|
|
fi
|
|
rm .tmp/sections.$$
|
|
if [ -n "$zmode" ]; then
|
|
LD_ORIGIN_PATH=/usr/bin eu-elfcompress --type=none "$f"
|
|
debugedit -b "$RPM_BUILD_DIR" -d /usr/src/debug -l .tmp/src.$$ "$f"
|
|
LD_ORIGIN_PATH=/usr/bin eu-elfcompress --type=$zmode "$f"
|
|
fi
|
|
fi
|
|
if [ -n "$strip" ]; then
|
|
mkdir -p "${debugf%/*}"
|
|
LD_ORIGIN_PATH=/usr/bin eu-strip $strip $strip_rel $strip_btf --remove-comment -f "$debugf" "$f"
|
|
|
|
if [ -n "$elfcompress" ] && [ -x /usr/bin/eu-elfcompress ]; then
|
|
LD_ORIGIN_PATH=/usr/bin eu-elfcompress --quiet "$debugf"
|
|
fi
|
|
|
|
touch --date=$timestamp "$debugf" "$f"
|
|
chmod 644 "$debugf"
|
|
else
|
|
touch --date=$timestamp "$f"
|
|
fi
|
|
|
|
mkdir -p .debuginfo/src/"${f%/*}"
|
|
awk 'BEGIN{RS="\0";ORS="\n"}{print}' .tmp/src.$$ |LC_ALL=C sort -u |
|
|
while read -r src; do
|
|
if [ -f "$RPM_BUILD_DIR"/"$src" ]; then
|
|
if [ ! -f ./usr/src/debug/"$src" ]; then
|
|
install -pD -m644 "$RPM_BUILD_DIR"/"$src" ./usr/src/debug/"$src".$$
|
|
mv -f ./usr/src/debug/"$src".$$ ./usr/src/debug/"$src"
|
|
fi
|
|
elif [ -d "$RPM_BUILD_DIR"/"$src" ]; then
|
|
mkdir -p ./usr/src/debug/"$src"
|
|
else
|
|
continue
|
|
fi
|
|
printf '%s\n' /usr/src/debug/"$src"
|
|
done >.debuginfo/src/"$f"
|
|
[ -s .tmp/src.$$ ] || printf '%s\n' "$f" >> .tmp/no_debug_info
|
|
rm .tmp/src.$$
|
|
|
|
if [ -n "$rezip" ]; then
|
|
# Compress module, move uncompressed into debug tree.
|
|
$rezip --keep --force "$f"
|
|
mv "$f" ./usr/lib/debug"${f#.}"
|
|
fi
|