From df57f906eb5909ac2093df01a94db6c0fb2f0e42 Mon Sep 17 00:00:00 2001 From: Eugene Syromiatnikov Date: Mon, 22 May 2023 17:53:44 +0200 Subject: [PATCH] find-provides.ksyms, find-requires.ksyms: do section data parsing inside awk MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Signed-off-by: Eugene Syromiatnikov --- find-provides.ksyms | 19 +++++++++++++------ find-requires.ksyms | 19 +++++++++++++------ 2 files changed, 26 insertions(+), 12 deletions(-) diff --git a/find-provides.ksyms b/find-provides.ksyms index 2c396f9..58ac4e8 100755 --- a/find-provides.ksyms +++ b/find-provides.ksyms @@ -50,19 +50,26 @@ for module in $(grep -E '/lib/modules/.+\.ko(\.gz|\.bz2|\.xz|\.zst)?$') "$@"; do | while read -r sectname; do [ -n "$sectname" ] || continue - revbytes="" kmod_elf_hdr="$(readelf -h "$module")" - [ "x$kmod_elf_hdr" = "x${kmod_elf_hdr%Data:*little endian*}" ] || - revbytes='a = gensub(/(..)(..)(..)(..)/, "\\4\\3\\2\\1", "g", a);' - SECTDATA=$(readelf -R "$sectname" "$module" | awk '/^ 0x[0-9a-f]{8}/{ a = substr($0, 14, 8) substr($0, 23, 8) substr($0, 32, 8) substr($0, 41, 8); '"$revbytes"' printf("%s", a); }') + [ "x$kmod_elf_hdr" = "x${kmod_elf_hdr%Data:*little endian*}" ] + revbytes="$?" objdump -t "$module" \ | awk \ -v 'dep_pfx='"$dep_pfx" \ - -v 'sectdata='"$SECTDATA" \ + -v 'module='"$module" \ + -v 'revbytes='"$revbytes" \ -v 'sectname='"$sectname" \ --non-decimal-data \ - '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)) }' + '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)) }' done fi diff --git a/find-requires.ksyms b/find-requires.ksyms index 7ece283..cda0ce2 100755 --- a/find-requires.ksyms +++ b/find-requires.ksyms @@ -52,19 +52,26 @@ all_provides() { | while read -r sectname; do [ -n "$sectname" ] || continue - revbytes="" kmod_elf_hdr="$(readelf -h "$module")" - [ "x$kmod_elf_hdr" = "x${kmod_elf_hdr%Data:*little endian*}" ] || - revbytes='a = gensub(/(..)(..)(..)(..)/, "\\4\\3\\2\\1", "g", a);' - SECTDATA=$(readelf -R "$sectname" "$module" | awk '/^ 0x[0-9a-f]{8}/{ a = substr($0, 14, 8) substr($0, 23, 8) substr($0, 32, 8) substr($0, 41, 8); '"$revbytes"' printf("%s", a); }') + [ "x$kmod_elf_hdr" = "x${kmod_elf_hdr%Data:*little endian*}" ] + revbytes="$?" objdump -t "$module" \ | awk \ -v 'dep_pfx='"$dep_pfx" \ - -v 'sectdata='"$SECTDATA" \ + -v 'module='"$module" \ + -v 'revbytes='"$revbytes" \ -v 'sectname='"$sectname" \ --non-decimal-data \ - '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)) }' + '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)) }' done fi