kernel-srpm-macros/find-requires.ksyms

200 lines
7.4 KiB
Plaintext
Raw Normal View History

#! /bin/bash
#
# This script is called during external module building to create dependencies
# both upon the RHEL kernel, and on additional external modules. Symbols that
# cannot be reconciled against those provided by the kernel are assumed to be
# provided by an external module and "ksym" replaces th regular "kernel" dep.
IFS=$'\n'
export LC_ALL=C
# Prevent elfutils from trying to download debuginfos
unset DEBUGINFOD_URLS
# Extract all of the symbols provided by this module.
all_provides() {
for module in "$@"; do
tmpfile=""
if [ "x${module%.ko}" = "x${module}" ]; then
tmpfile=$(mktemp -t ${0##*/}.XXXXXX.ko)
proc_bin=
case "${module##*.}" in
zst)
proc_bin=zstd
;;
xz)
proc_bin=xz
;;
bz2)
proc_bin=bzip2
;;
gz)
proc_bin=gzip
;;
esac
[ -n "$proc_bin" ] || continue
"$proc_bin" -d -c - < "$module" > "$tmpfile" || continue
module="$tmpfile"
fi
find-provides.ksyms, find-requires.ksyms: avoid calling nm twice Instead of running the nm output through grep and then running it through awk again, run it directly through awk, and bail of immediately if a non-absolute symbol is found. Also, while we're here, avoid executing the indirect parsing code if no __crc_* symbols are present at all, which shaves around 8-18% off of the run time: % for i in ./lib/modules/*; do \ echo "====== $i ====="; \ diff -u <(find $i | ./find-provides.ksyms.old) <(find $i | ./find-provides.ksyms.new); \ echo old:; find $i | time ./find-provides.ksyms.old > /dev/null; \ echo new:; find $i | time ./find-provides.ksyms.new > /dev/null; \ done ====== ./lib/modules/4.18.0-372.57.1.el8_6.s390x ===== old: ../find-provides.ksyms.old > /dev/null 5.10s user 4.52s system 150% cpu 6.412 total new: ../find-provides.ksyms.new > /dev/null 4.41s user 3.48s system 136% cpu 5.764 total ====== ./lib/modules/4.18.0-372.57.1.el8_6.x86_64 ===== old: ../find-provides.ksyms.old > /dev/null 7.80s user 6.19s system 143% cpu 9.740 total new: ../find-provides.ksyms.new > /dev/null 6.07s user 3.97s system 124% cpu 8.066 total ====== ./lib/modules/5.14.0-284.15.1.el9_2.s390x ===== old: ../find-provides.ksyms.old > /dev/null 5.87s user 4.35s system 143% cpu 7.113 total new: ../find-provides.ksyms.new > /dev/null 5.12s user 3.56s system 132% cpu 6.533 total ====== ./lib/modules/5.14.0-284.15.1.el9_2.x86_64 ===== old: ../find-provides.ksyms.old > /dev/null 8.44s user 6.78s system 144% cpu 10.535 total new: ../find-provides.ksyms.new > /dev/null 6.55s user 4.17s system 123% cpu 8.666 total ====== ./lib/modules/6.4.0-0.rc1.20230511git80e62bc8487b.19.eln126.s390x ===== old: ../find-provides.ksyms.old > /dev/null 5.04s user 3.95s system 145% cpu 6.166 total new: ../find-provides.ksyms.new > /dev/null 4.64s user 3.17s system 136% cpu 5.719 total ====== ./lib/modules/6.4.0-0.rc1.20230511git80e62bc8487b.19.eln126.x86_64 ===== old: ../find-provides.ksyms.old > /dev/null 8.49s user 5.54s system 139% cpu 10.043 total new: ../find-provides.ksyms.new > /dev/null 7.41s user 4.31s system 129% cpu 9.046 total * find-provides.ksyms: Rewrite the "if nm | grep -q; then nm | awk" with straight "nm | awk", update the awk script to return the exit code accordingly, execute indirect symbol parsing only if inderect __crc_* symbols are present. * find-requires.ksyms (all_provides): Likewise. Signed-off-by: Eugene Syromiatnikov <esyr@redhat.com>
2023-05-23 13:02:19 +00:00
# awk script return code:
# 0 - absolute __crc_* symbols have been found, output has been
# generated;
# 23 - a non-absolute __crc_* symbold has been found;
# 42 - no __crc_* symbols have been found.
nm "$module" \
| awk \
-v 'dep_pfx='"$dep_pfx" \
--non-decimal-data \
'BEGIN { exit_code = 42 }
match($0, /^([0-9a-f]+) (.) __crc_(.+)/, a) {
if (a[2] == "A") {
printf("%s(%s) = 0x%08x\n", dep_pfx, a[3], strtonum("0x" a[1]));
exit_code = 0;
} else {
exit_code = 23;
exit;
}
}
END { exit exit_code }'
[ 23 = "$?" ] && {
find-provides.ksyms, find-requires.ksyms: rewrite indirect CRC parsing Linux commit v5.19-rc1~139^2~2 ("kbuild: link symbol CRCs at final link, removing CONFIG_MODULE_REL_CRCS") has broken the assumption aobut the placement of non-absolute CRC symbols in .rodata (and also affects the architectures that used to have these symbols as absolute); rewrite the parsing by utilising "objdump -t" output to figure out the section(s) where the __crc_* symbols are stored and process it instead of the hard-coded ".rodata" section. The change also speeds up the processing a bit, around 33% on synthetic tests: $ time sh -c 'find ./lib/modules/5.14.0-258.el9.ppc64le -name "*.ko.xz" | find-provides.ksyms.old > /dev/null 2> /dev/null' sh -c 10.36s user 5.58s system 137% cpu 11.613 total $ time sh -c 'find ./lib/modules/5.14.0-258.el9.ppc64le -name "*.ko.xz" | find-provides.ksyms.new > /dev/null 2> /dev/null' sh -c 7.82s user 4.59s system 142% cpu 8.686 total $ time sh -c 'find ./lib/modules/5.14.0-258.el9.ppc64le -name "*.ko.xz" -exec sh -c "echo {} | find-provides.ksyms.old" \; > /dev/null 2> /dev/null' sh -c 11.85s user 6.76s system 129% cpu 14.318 total $ time sh -c 'find ./lib/modules/5.14.0-258.el9.ppc64le -name "*.ko.xz" -exec sh -c "echo {} | find-provides.ksyms.new" \; > /dev/null 2> /dev/null' sh -c 8.91s user 5.51s system 135% cpu 10.647 total * find-provides.ksyms: Process "objdump -t" output to get the list of sections where __crc_* symbol contents are placed; retrieve each one with "readelf -R" and supply it to an awk script that cuts the required part of it for each __crc_* symbol in that section. * find-requires.ksyms (all_provides): Likewise. Signed-off-by: Eugene Syromiatnikov <esyr@redhat.com> Resolves: #2135047
2023-02-05 00:26:01 +00:00
objdump -t "$module" \
| sed -n 's/^[0-9a-f][0-9a-f]* [gl]...... \(.*\) [0-9a-f][0-9a-f]* __crc_.*$/\1/p' \
find-provides.ksyms, find-requires.ksyms: rewrite indirect CRC parsing Linux commit v5.19-rc1~139^2~2 ("kbuild: link symbol CRCs at final link, removing CONFIG_MODULE_REL_CRCS") has broken the assumption aobut the placement of non-absolute CRC symbols in .rodata (and also affects the architectures that used to have these symbols as absolute); rewrite the parsing by utilising "objdump -t" output to figure out the section(s) where the __crc_* symbols are stored and process it instead of the hard-coded ".rodata" section. The change also speeds up the processing a bit, around 33% on synthetic tests: $ time sh -c 'find ./lib/modules/5.14.0-258.el9.ppc64le -name "*.ko.xz" | find-provides.ksyms.old > /dev/null 2> /dev/null' sh -c 10.36s user 5.58s system 137% cpu 11.613 total $ time sh -c 'find ./lib/modules/5.14.0-258.el9.ppc64le -name "*.ko.xz" | find-provides.ksyms.new > /dev/null 2> /dev/null' sh -c 7.82s user 4.59s system 142% cpu 8.686 total $ time sh -c 'find ./lib/modules/5.14.0-258.el9.ppc64le -name "*.ko.xz" -exec sh -c "echo {} | find-provides.ksyms.old" \; > /dev/null 2> /dev/null' sh -c 11.85s user 6.76s system 129% cpu 14.318 total $ time sh -c 'find ./lib/modules/5.14.0-258.el9.ppc64le -name "*.ko.xz" -exec sh -c "echo {} | find-provides.ksyms.new" \; > /dev/null 2> /dev/null' sh -c 8.91s user 5.51s system 135% cpu 10.647 total * find-provides.ksyms: Process "objdump -t" output to get the list of sections where __crc_* symbol contents are placed; retrieve each one with "readelf -R" and supply it to an awk script that cuts the required part of it for each __crc_* symbol in that section. * find-requires.ksyms (all_provides): Likewise. Signed-off-by: Eugene Syromiatnikov <esyr@redhat.com> Resolves: #2135047
2023-02-05 00:26:01 +00:00
| sort -u \
| while read -r sectname; do
find-provides.ksyms, find-requires.ksyms: rewrite indirect CRC parsing Linux commit v5.19-rc1~139^2~2 ("kbuild: link symbol CRCs at final link, removing CONFIG_MODULE_REL_CRCS") has broken the assumption aobut the placement of non-absolute CRC symbols in .rodata (and also affects the architectures that used to have these symbols as absolute); rewrite the parsing by utilising "objdump -t" output to figure out the section(s) where the __crc_* symbols are stored and process it instead of the hard-coded ".rodata" section. The change also speeds up the processing a bit, around 33% on synthetic tests: $ time sh -c 'find ./lib/modules/5.14.0-258.el9.ppc64le -name "*.ko.xz" | find-provides.ksyms.old > /dev/null 2> /dev/null' sh -c 10.36s user 5.58s system 137% cpu 11.613 total $ time sh -c 'find ./lib/modules/5.14.0-258.el9.ppc64le -name "*.ko.xz" | find-provides.ksyms.new > /dev/null 2> /dev/null' sh -c 7.82s user 4.59s system 142% cpu 8.686 total $ time sh -c 'find ./lib/modules/5.14.0-258.el9.ppc64le -name "*.ko.xz" -exec sh -c "echo {} | find-provides.ksyms.old" \; > /dev/null 2> /dev/null' sh -c 11.85s user 6.76s system 129% cpu 14.318 total $ time sh -c 'find ./lib/modules/5.14.0-258.el9.ppc64le -name "*.ko.xz" -exec sh -c "echo {} | find-provides.ksyms.new" \; > /dev/null 2> /dev/null' sh -c 8.91s user 5.51s system 135% cpu 10.647 total * find-provides.ksyms: Process "objdump -t" output to get the list of sections where __crc_* symbol contents are placed; retrieve each one with "readelf -R" and supply it to an awk script that cuts the required part of it for each __crc_* symbol in that section. * find-requires.ksyms (all_provides): Likewise. Signed-off-by: Eugene Syromiatnikov <esyr@redhat.com> Resolves: #2135047
2023-02-05 00:26:01 +00:00
[ -n "$sectname" ] || continue
kmod_elf_hdr="$(readelf -h "$module")"
find-provides.ksyms, find-requires.ksyms: do section data parsing inside awk Previous approach with passing the section contents as a command line option proven to be error-prone, as it hits the command line option size limit on some kmods. Move the reading and processing of the section contents inside the awk script itself; it also saves a bit (around 3—4%) of time on the kernels with indirect __crc_* symbols: $ for i in ./lib/modules/*; do \ echo "====== $i ====="; \ diff -u <(find $i | ./find-provides.ksyms.old) <(find $i | ./find-provides.ksyms.new); \ echo -n "old: "; find $i | time ./find-provides.ksyms.old > /dev/null; \ echo -n "new: "; find $i | time ./find-provides.ksyms.new > /dev/null; \ done ====== ./lib/modules/4.18.0-372.57.1.el8_6.s390x ===== old: ./find-provides.ksyms.old > /dev/null 5.38s user 4.66s system 150% cpu 6.693 total new: ./find-provides.ksyms.new > /dev/null 5.20s user 4.52s system 149% cpu 6.484 total ====== ./lib/modules/4.18.0-372.57.1.el8_6.x86_64 ===== old: ./find-provides.ksyms.old > /dev/null 7.85s user 6.34s system 143% cpu 9.864 total new: ./find-provides.ksyms.new > /dev/null 7.75s user 6.32s system 143% cpu 9.809 total ====== ./lib/modules/5.14.0-284.15.1.el9_2.s390x ===== old: ./find-provides.ksyms.old > /dev/null 6.19s user 4.68s system 144% cpu 7.506 total new: ./find-provides.ksyms.new > /dev/null 5.93s user 4.46s system 143% cpu 7.219 total ====== ./lib/modules/5.14.0-284.15.1.el9_2.x86_64 ===== old: ./find-provides.ksyms.old > /dev/null 8.47s user 6.71s system 144% cpu 10.523 total new: ./find-provides.ksyms.new > /dev/null 8.44s user 6.59s system 144% cpu 10.435 total ====== ./lib/modules/6.4.0-0.rc1.20230511git80e62bc8487b.19.eln126.s390x ===== old: ./find-provides.ksyms.old > /dev/null 5.21s user 4.09s system 145% cpu 6.383 total new: ./find-provides.ksyms.new > /dev/null 5.04s user 3.85s system 145% cpu 6.120 total ====== ./lib/modules/6.4.0-0.rc1.20230511git80e62bc8487b.19.eln126.x86_64 ===== old: ./find-provides.ksyms.old > /dev/null 8.68s user 5.77s system 139% cpu 10.326 total new: ./find-provides.ksyms.new > /dev/null 8.47s user 5.57s system 139% cpu 10.067 total * find-provides.ksyms: Add assign to revbytes the result of endianness chack test instead of the code snippet; do not generate SECTDATA variable; do not pass SECTDATA to the awk script; pass module and revbytes to the awk script; retrieve the section data into the sectdata variable and perform the byte re-shuffling in accordance to the revbytes value in the BEGIN section of the awk script. * find-requires.ksyms (all_provides): Likewise. Fixes: cd7e9e8a2fc2 "find-provides.ksyms, find-requires.ksyms: rewrite indirect CRC parsing" Resolves: #2135901 References: https://bugzilla.redhat.com/show_bug.cgi?id=2178935 Co-Authored-by: Denys Vlasenko <dvlasenk@redhat.com> Signed-off-by: Eugene Syromiatnikov <esyr@redhat.com>
2023-05-22 15:53:44 +00:00
[ "x$kmod_elf_hdr" = "x${kmod_elf_hdr%Data:*little endian*}" ]
revbytes="$?"
find-provides.ksyms, find-requires.ksyms: rewrite indirect CRC parsing Linux commit v5.19-rc1~139^2~2 ("kbuild: link symbol CRCs at final link, removing CONFIG_MODULE_REL_CRCS") has broken the assumption aobut the placement of non-absolute CRC symbols in .rodata (and also affects the architectures that used to have these symbols as absolute); rewrite the parsing by utilising "objdump -t" output to figure out the section(s) where the __crc_* symbols are stored and process it instead of the hard-coded ".rodata" section. The change also speeds up the processing a bit, around 33% on synthetic tests: $ time sh -c 'find ./lib/modules/5.14.0-258.el9.ppc64le -name "*.ko.xz" | find-provides.ksyms.old > /dev/null 2> /dev/null' sh -c 10.36s user 5.58s system 137% cpu 11.613 total $ time sh -c 'find ./lib/modules/5.14.0-258.el9.ppc64le -name "*.ko.xz" | find-provides.ksyms.new > /dev/null 2> /dev/null' sh -c 7.82s user 4.59s system 142% cpu 8.686 total $ time sh -c 'find ./lib/modules/5.14.0-258.el9.ppc64le -name "*.ko.xz" -exec sh -c "echo {} | find-provides.ksyms.old" \; > /dev/null 2> /dev/null' sh -c 11.85s user 6.76s system 129% cpu 14.318 total $ time sh -c 'find ./lib/modules/5.14.0-258.el9.ppc64le -name "*.ko.xz" -exec sh -c "echo {} | find-provides.ksyms.new" \; > /dev/null 2> /dev/null' sh -c 8.91s user 5.51s system 135% cpu 10.647 total * find-provides.ksyms: Process "objdump -t" output to get the list of sections where __crc_* symbol contents are placed; retrieve each one with "readelf -R" and supply it to an awk script that cuts the required part of it for each __crc_* symbol in that section. * find-requires.ksyms (all_provides): Likewise. Signed-off-by: Eugene Syromiatnikov <esyr@redhat.com> Resolves: #2135047
2023-02-05 00:26:01 +00:00
objdump -t "$module" \
| awk \
-v 'dep_pfx='"$dep_pfx" \
find-provides.ksyms, find-requires.ksyms: do section data parsing inside awk Previous approach with passing the section contents as a command line option proven to be error-prone, as it hits the command line option size limit on some kmods. Move the reading and processing of the section contents inside the awk script itself; it also saves a bit (around 3—4%) of time on the kernels with indirect __crc_* symbols: $ for i in ./lib/modules/*; do \ echo "====== $i ====="; \ diff -u <(find $i | ./find-provides.ksyms.old) <(find $i | ./find-provides.ksyms.new); \ echo -n "old: "; find $i | time ./find-provides.ksyms.old > /dev/null; \ echo -n "new: "; find $i | time ./find-provides.ksyms.new > /dev/null; \ done ====== ./lib/modules/4.18.0-372.57.1.el8_6.s390x ===== old: ./find-provides.ksyms.old > /dev/null 5.38s user 4.66s system 150% cpu 6.693 total new: ./find-provides.ksyms.new > /dev/null 5.20s user 4.52s system 149% cpu 6.484 total ====== ./lib/modules/4.18.0-372.57.1.el8_6.x86_64 ===== old: ./find-provides.ksyms.old > /dev/null 7.85s user 6.34s system 143% cpu 9.864 total new: ./find-provides.ksyms.new > /dev/null 7.75s user 6.32s system 143% cpu 9.809 total ====== ./lib/modules/5.14.0-284.15.1.el9_2.s390x ===== old: ./find-provides.ksyms.old > /dev/null 6.19s user 4.68s system 144% cpu 7.506 total new: ./find-provides.ksyms.new > /dev/null 5.93s user 4.46s system 143% cpu 7.219 total ====== ./lib/modules/5.14.0-284.15.1.el9_2.x86_64 ===== old: ./find-provides.ksyms.old > /dev/null 8.47s user 6.71s system 144% cpu 10.523 total new: ./find-provides.ksyms.new > /dev/null 8.44s user 6.59s system 144% cpu 10.435 total ====== ./lib/modules/6.4.0-0.rc1.20230511git80e62bc8487b.19.eln126.s390x ===== old: ./find-provides.ksyms.old > /dev/null 5.21s user 4.09s system 145% cpu 6.383 total new: ./find-provides.ksyms.new > /dev/null 5.04s user 3.85s system 145% cpu 6.120 total ====== ./lib/modules/6.4.0-0.rc1.20230511git80e62bc8487b.19.eln126.x86_64 ===== old: ./find-provides.ksyms.old > /dev/null 8.68s user 5.77s system 139% cpu 10.326 total new: ./find-provides.ksyms.new > /dev/null 8.47s user 5.57s system 139% cpu 10.067 total * find-provides.ksyms: Add assign to revbytes the result of endianness chack test instead of the code snippet; do not generate SECTDATA variable; do not pass SECTDATA to the awk script; pass module and revbytes to the awk script; retrieve the section data into the sectdata variable and perform the byte re-shuffling in accordance to the revbytes value in the BEGIN section of the awk script. * find-requires.ksyms (all_provides): Likewise. Fixes: cd7e9e8a2fc2 "find-provides.ksyms, find-requires.ksyms: rewrite indirect CRC parsing" Resolves: #2135901 References: https://bugzilla.redhat.com/show_bug.cgi?id=2178935 Co-Authored-by: Denys Vlasenko <dvlasenk@redhat.com> Signed-off-by: Eugene Syromiatnikov <esyr@redhat.com>
2023-05-22 15:53:44 +00:00
-v 'module='"$module" \
-v 'revbytes='"$revbytes" \
-v 'sectname='"$sectname" \
find-provides.ksyms, find-requires.ksyms: rewrite indirect CRC parsing Linux commit v5.19-rc1~139^2~2 ("kbuild: link symbol CRCs at final link, removing CONFIG_MODULE_REL_CRCS") has broken the assumption aobut the placement of non-absolute CRC symbols in .rodata (and also affects the architectures that used to have these symbols as absolute); rewrite the parsing by utilising "objdump -t" output to figure out the section(s) where the __crc_* symbols are stored and process it instead of the hard-coded ".rodata" section. The change also speeds up the processing a bit, around 33% on synthetic tests: $ time sh -c 'find ./lib/modules/5.14.0-258.el9.ppc64le -name "*.ko.xz" | find-provides.ksyms.old > /dev/null 2> /dev/null' sh -c 10.36s user 5.58s system 137% cpu 11.613 total $ time sh -c 'find ./lib/modules/5.14.0-258.el9.ppc64le -name "*.ko.xz" | find-provides.ksyms.new > /dev/null 2> /dev/null' sh -c 7.82s user 4.59s system 142% cpu 8.686 total $ time sh -c 'find ./lib/modules/5.14.0-258.el9.ppc64le -name "*.ko.xz" -exec sh -c "echo {} | find-provides.ksyms.old" \; > /dev/null 2> /dev/null' sh -c 11.85s user 6.76s system 129% cpu 14.318 total $ time sh -c 'find ./lib/modules/5.14.0-258.el9.ppc64le -name "*.ko.xz" -exec sh -c "echo {} | find-provides.ksyms.new" \; > /dev/null 2> /dev/null' sh -c 8.91s user 5.51s system 135% cpu 10.647 total * find-provides.ksyms: Process "objdump -t" output to get the list of sections where __crc_* symbol contents are placed; retrieve each one with "readelf -R" and supply it to an awk script that cuts the required part of it for each __crc_* symbol in that section. * find-requires.ksyms (all_provides): Likewise. Signed-off-by: Eugene Syromiatnikov <esyr@redhat.com> Resolves: #2135047
2023-02-05 00:26:01 +00:00
--non-decimal-data \
find-provides.ksyms, find-requires.ksyms: do section data parsing inside awk Previous approach with passing the section contents as a command line option proven to be error-prone, as it hits the command line option size limit on some kmods. Move the reading and processing of the section contents inside the awk script itself; it also saves a bit (around 3—4%) of time on the kernels with indirect __crc_* symbols: $ for i in ./lib/modules/*; do \ echo "====== $i ====="; \ diff -u <(find $i | ./find-provides.ksyms.old) <(find $i | ./find-provides.ksyms.new); \ echo -n "old: "; find $i | time ./find-provides.ksyms.old > /dev/null; \ echo -n "new: "; find $i | time ./find-provides.ksyms.new > /dev/null; \ done ====== ./lib/modules/4.18.0-372.57.1.el8_6.s390x ===== old: ./find-provides.ksyms.old > /dev/null 5.38s user 4.66s system 150% cpu 6.693 total new: ./find-provides.ksyms.new > /dev/null 5.20s user 4.52s system 149% cpu 6.484 total ====== ./lib/modules/4.18.0-372.57.1.el8_6.x86_64 ===== old: ./find-provides.ksyms.old > /dev/null 7.85s user 6.34s system 143% cpu 9.864 total new: ./find-provides.ksyms.new > /dev/null 7.75s user 6.32s system 143% cpu 9.809 total ====== ./lib/modules/5.14.0-284.15.1.el9_2.s390x ===== old: ./find-provides.ksyms.old > /dev/null 6.19s user 4.68s system 144% cpu 7.506 total new: ./find-provides.ksyms.new > /dev/null 5.93s user 4.46s system 143% cpu 7.219 total ====== ./lib/modules/5.14.0-284.15.1.el9_2.x86_64 ===== old: ./find-provides.ksyms.old > /dev/null 8.47s user 6.71s system 144% cpu 10.523 total new: ./find-provides.ksyms.new > /dev/null 8.44s user 6.59s system 144% cpu 10.435 total ====== ./lib/modules/6.4.0-0.rc1.20230511git80e62bc8487b.19.eln126.s390x ===== old: ./find-provides.ksyms.old > /dev/null 5.21s user 4.09s system 145% cpu 6.383 total new: ./find-provides.ksyms.new > /dev/null 5.04s user 3.85s system 145% cpu 6.120 total ====== ./lib/modules/6.4.0-0.rc1.20230511git80e62bc8487b.19.eln126.x86_64 ===== old: ./find-provides.ksyms.old > /dev/null 8.68s user 5.77s system 139% cpu 10.326 total new: ./find-provides.ksyms.new > /dev/null 8.47s user 5.57s system 139% cpu 10.067 total * find-provides.ksyms: Add assign to revbytes the result of endianness chack test instead of the code snippet; do not generate SECTDATA variable; do not pass SECTDATA to the awk script; pass module and revbytes to the awk script; retrieve the section data into the sectdata variable and perform the byte re-shuffling in accordance to the revbytes value in the BEGIN section of the awk script. * find-requires.ksyms (all_provides): Likewise. Fixes: cd7e9e8a2fc2 "find-provides.ksyms, find-requires.ksyms: rewrite indirect CRC parsing" Resolves: #2135901 References: https://bugzilla.redhat.com/show_bug.cgi?id=2178935 Co-Authored-by: Denys Vlasenko <dvlasenk@redhat.com> Signed-off-by: Eugene Syromiatnikov <esyr@redhat.com>
2023-05-22 15:53:44 +00:00
'BEGIN {
sectdata = "";
while (("readelf -R \"" sectname "\" \"" module "\"" | getline t) > 0) {
if (match(t, /^ 0x[0-9a-f]{8}/))
sectdata = sectdata substr(t, 14, 8) substr(t, 23, 8) substr(t, 32, 8) substr(t, 41, 8);
}
if (revbytes) { sectdata = gensub(/(..)(..)(..)(..)/, "\\4\\3\\2\\1", "g", sectdata); }
}
match($0, /^([0-9a-f]+) [gl]...... (.*) [0-9a-f]+ __crc_(.*)$/, a) && a[2] == sectname { printf("%s(%s) = 0x%08s\n", dep_pfx, a[3], substr(sectdata, (strtonum("0x" a[1]) * 2) + 1, 8)) }'
find-provides.ksyms, find-requires.ksyms: rewrite indirect CRC parsing Linux commit v5.19-rc1~139^2~2 ("kbuild: link symbol CRCs at final link, removing CONFIG_MODULE_REL_CRCS") has broken the assumption aobut the placement of non-absolute CRC symbols in .rodata (and also affects the architectures that used to have these symbols as absolute); rewrite the parsing by utilising "objdump -t" output to figure out the section(s) where the __crc_* symbols are stored and process it instead of the hard-coded ".rodata" section. The change also speeds up the processing a bit, around 33% on synthetic tests: $ time sh -c 'find ./lib/modules/5.14.0-258.el9.ppc64le -name "*.ko.xz" | find-provides.ksyms.old > /dev/null 2> /dev/null' sh -c 10.36s user 5.58s system 137% cpu 11.613 total $ time sh -c 'find ./lib/modules/5.14.0-258.el9.ppc64le -name "*.ko.xz" | find-provides.ksyms.new > /dev/null 2> /dev/null' sh -c 7.82s user 4.59s system 142% cpu 8.686 total $ time sh -c 'find ./lib/modules/5.14.0-258.el9.ppc64le -name "*.ko.xz" -exec sh -c "echo {} | find-provides.ksyms.old" \; > /dev/null 2> /dev/null' sh -c 11.85s user 6.76s system 129% cpu 14.318 total $ time sh -c 'find ./lib/modules/5.14.0-258.el9.ppc64le -name "*.ko.xz" -exec sh -c "echo {} | find-provides.ksyms.new" \; > /dev/null 2> /dev/null' sh -c 8.91s user 5.51s system 135% cpu 10.647 total * find-provides.ksyms: Process "objdump -t" output to get the list of sections where __crc_* symbol contents are placed; retrieve each one with "readelf -R" and supply it to an awk script that cuts the required part of it for each __crc_* symbol in that section. * find-requires.ksyms (all_provides): Likewise. Signed-off-by: Eugene Syromiatnikov <esyr@redhat.com> Resolves: #2135047
2023-02-05 00:26:01 +00:00
done
find-provides.ksyms, find-requires.ksyms: avoid calling nm twice Instead of running the nm output through grep and then running it through awk again, run it directly through awk, and bail of immediately if a non-absolute symbol is found. Also, while we're here, avoid executing the indirect parsing code if no __crc_* symbols are present at all, which shaves around 8-18% off of the run time: % for i in ./lib/modules/*; do \ echo "====== $i ====="; \ diff -u <(find $i | ./find-provides.ksyms.old) <(find $i | ./find-provides.ksyms.new); \ echo old:; find $i | time ./find-provides.ksyms.old > /dev/null; \ echo new:; find $i | time ./find-provides.ksyms.new > /dev/null; \ done ====== ./lib/modules/4.18.0-372.57.1.el8_6.s390x ===== old: ../find-provides.ksyms.old > /dev/null 5.10s user 4.52s system 150% cpu 6.412 total new: ../find-provides.ksyms.new > /dev/null 4.41s user 3.48s system 136% cpu 5.764 total ====== ./lib/modules/4.18.0-372.57.1.el8_6.x86_64 ===== old: ../find-provides.ksyms.old > /dev/null 7.80s user 6.19s system 143% cpu 9.740 total new: ../find-provides.ksyms.new > /dev/null 6.07s user 3.97s system 124% cpu 8.066 total ====== ./lib/modules/5.14.0-284.15.1.el9_2.s390x ===== old: ../find-provides.ksyms.old > /dev/null 5.87s user 4.35s system 143% cpu 7.113 total new: ../find-provides.ksyms.new > /dev/null 5.12s user 3.56s system 132% cpu 6.533 total ====== ./lib/modules/5.14.0-284.15.1.el9_2.x86_64 ===== old: ../find-provides.ksyms.old > /dev/null 8.44s user 6.78s system 144% cpu 10.535 total new: ../find-provides.ksyms.new > /dev/null 6.55s user 4.17s system 123% cpu 8.666 total ====== ./lib/modules/6.4.0-0.rc1.20230511git80e62bc8487b.19.eln126.s390x ===== old: ../find-provides.ksyms.old > /dev/null 5.04s user 3.95s system 145% cpu 6.166 total new: ../find-provides.ksyms.new > /dev/null 4.64s user 3.17s system 136% cpu 5.719 total ====== ./lib/modules/6.4.0-0.rc1.20230511git80e62bc8487b.19.eln126.x86_64 ===== old: ../find-provides.ksyms.old > /dev/null 8.49s user 5.54s system 139% cpu 10.043 total new: ../find-provides.ksyms.new > /dev/null 7.41s user 4.31s system 129% cpu 9.046 total * find-provides.ksyms: Rewrite the "if nm | grep -q; then nm | awk" with straight "nm | awk", update the awk script to return the exit code accordingly, execute indirect symbol parsing only if inderect __crc_* symbols are present. * find-requires.ksyms (all_provides): Likewise. Signed-off-by: Eugene Syromiatnikov <esyr@redhat.com>
2023-05-23 13:02:19 +00:00
}
[ -z "$tmpfile" ] || rm -f -- "$tmpfile"
done \
| sort -k1,1 -u
}
# Extract all of the requirements of this module.
all_requires() {
for module in "$@"; do
set -- $(/sbin/modinfo -F vermagic "$module" | sed -e 's: .*::' -e q)
/sbin/modprobe --dump-modversions "$module" \
| awk --non-decimal-data '
BEGIN { FS = "\t" ; OFS = "\t" }
{printf("%s:0x%08x\n", $2, $1)}' \
| sed -r -e 's:$:\t'"$1"':'
done \
| sort -k1,1 -u
}
# Filter out requirements fulfilled by the module itself.
mod_requires() {
join -t $'\t' -j 1 -v 1 \
<(all_requires "$@") \
<(all_provides "$@") \
| sort -k1,1 -u
}
if ! [ -e /sbin/modinfo -a -e /sbin/modprobe ]; then
cat > /dev/null
exit 0
fi
check_kabi() {
arch=$(uname -m)
kabi_file="/lib/modules/kabi-current/kabi_stablelist_$arch"
# If not installed, output a warning and return (continue)
if [ ! -f "$kabi_file" ]; then
echo "" >&2
echo "********************************************************************************" >&2
echo "*********************** KERNEL ABI COMPATIBILITY WARNING ***********************" >&2
echo "********************************************************************************" >&2
echo "The kernel ABI reference files (provided by "kabi-stablelists") were not found." >&2
echo "No compatibility check was performed. Please install the kABI reference files" >&2
echo "and rebuild if you would like to verify compatibility with kernel ABI." >&2
echo "" >&2
return
fi
unset non_kabi
for symbol in "$@"; do
if ! egrep "^[[:space:]]$symbol\$" $kabi_file >/dev/null; then
non_kabi=("${non_kabi[@]}" "$symbol")
fi
done
if [ ${#non_kabi[@]} -gt 0 ]; then
echo "" >&2
echo "********************************************************************************" >&2
echo "*********************** KERNEL ABI COMPATIBILITY WARNING ***********************" >&2
echo "********************************************************************************" >&2
echo "The following kernel symbols are not guaranteed to remain compatible with" >&2
echo "future kernel updates to this RHEL release:" >&2
echo "" >&2
for symbol in "${non_kabi[@]}"; do
printf "\t$symbol\n" >&2
done
echo "" >&2
echo "Red Hat recommends that you consider using only official kernel ABI symbols" >&2
echo "where possible. Requests for additions to the kernel ABI can be filed with" >&2
echo "your partner or customer representative (component: driver-update-program)." >&2
echo "" >&2
fi
}
modules=($(grep -E '/lib/modules/.+\.ko(\.gz|\.bz2|\.xz|\.zst)?$') "$@")
if [ ${#modules[@]} -gt 0 ]; then
kernel=$(/sbin/modinfo -F vermagic "${modules[0]}" | sed -e 's: .*::' -e q)
# get all that kernel provides
symvers=$(mktemp -t ${0##*/}.XXXXX)
cat /usr/src/kernels/$kernel/Module.symvers | awk '
BEGIN { FS = "\t" ; OFS = "\t" }
{ print $2 ":" $1 }
' \
| sed -r -e 's:$:\t'"$kernel"':' \
| sort -k1,1 -u > $symvers
# Symbols matching with the kernel get a "kernel" dependency
mod_req=$(mktemp -t mod_req.XXXXX)
mod_requires "${modules[@]}" > "$mod_req"
join -t $'\t' -j 1 $symvers "$mod_req" | sort -u \
| awk 'BEGIN { FS = "[\t:]" ; OFS = "\t" } { print "kernel(" $1 ") = " $2 }'
# Symbols from elsewhere get a "ksym" dependency
join -t $'\t' -j 1 -v 2 $symvers "$mod_req" | sort -u \
| awk 'BEGIN { FS = "[\t:]" ; OFS = "\t" } { print "ksym(" $1 ") = " $2 }'
os_id=$(sed -nr '/^ID[[:space:]]*=/{ s/ID[[:space:]]*=[[:space:]]*//; s/^"(.*)"$/\1/; p }' /etc/os-release)
if [ "rhel" = "$os_id" ]; then
# Check kABI if the kabi-stablelists package is installed
# Do this last so we can try to output this error at the end
kabi_check_symbols=($(join -t $'\t' -j 1 $symvers "$mod_req" | sort -u \
| awk 'BEGIN { FS = "[\t:]" ; OFS = "\t" } { print $1 }'))
check_kabi "${kabi_check_symbols[@]}"
fi
fi