diff options
author | Brian Johannesmeyer <bjohannesmeyer@gmail.com> | 2024-04-15 16:55:32 +0200 |
---|---|---|
committer | Josh Poimboeuf <jpoimboe@kernel.org> | 2024-07-03 08:38:36 +0200 |
commit | 39cf650d68289d41d484f4c29fea0124df2e09aa (patch) | |
tree | e4e4c60527c298d067faa1a700e63201ff1c500b /scripts/faddr2line | |
parent | Linux 6.10-rc6 (diff) | |
download | linux-39cf650d68289d41d484f4c29fea0124df2e09aa.tar.xz linux-39cf650d68289d41d484f4c29fea0124df2e09aa.zip |
scripts/faddr2line: Reduce number of readelf calls to three
Rather than calling readelf several times for each invocation of
__faddr2line, call readelf only three times at the beginning, and save its
result for future use.
Signed-off-by: Brian Johannesmeyer <bjohannesmeyer@gmail.com>
Link: https://lore.kernel.org/r/20240415145538.1938745-2-bjohannesmeyer@gmail.com
Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
Diffstat (limited to 'scripts/faddr2line')
-rwxr-xr-x | scripts/faddr2line | 26 |
1 files changed, 17 insertions, 9 deletions
diff --git a/scripts/faddr2line b/scripts/faddr2line index 587415a52b6f..bf394bfd526a 100755 --- a/scripts/faddr2line +++ b/scripts/faddr2line @@ -87,7 +87,7 @@ command -v ${ADDR2LINE} >/dev/null 2>&1 || die "${ADDR2LINE} isn't installed" find_dir_prefix() { local objfile=$1 - local start_kernel_addr=$(${READELF} --symbols --wide $objfile | sed 's/\[.*\]//' | + local start_kernel_addr=$(echo "${ELF_SYMS}" | sed 's/\[.*\]//' | ${AWK} '$8 == "start_kernel" {printf "0x%s", $2}') [[ -z $start_kernel_addr ]] && return @@ -103,6 +103,14 @@ find_dir_prefix() { return 0 } +run_readelf() { + local objfile=$1 + + ELF_FILEHEADER=$(${READELF} --file-header $objfile) + ELF_SECHEADERS=$(${READELF} --section-headers --wide $objfile) + ELF_SYMS=$(${READELF} --symbols --wide $objfile) +} + __faddr2line() { local objfile=$1 local func_addr=$2 @@ -125,7 +133,7 @@ __faddr2line() { # vmlinux uses absolute addresses in the section table rather than # section offsets. - local file_type=$(${READELF} --file-header $objfile | + local file_type=$(echo "${ELF_FILEHEADER}" | ${AWK} '$1 == "Type:" { print $2; exit }') if [[ $file_type = "EXEC" ]] || [[ $file_type == "DYN" ]]; then is_vmlinux=1 @@ -143,8 +151,7 @@ __faddr2line() { local sec_name # Get the section size: - sec_size=$(${READELF} --section-headers --wide $objfile | - sed 's/\[ /\[/' | + sec_size=$(echo "${ELF_SECHEADERS}" | sed 's/\[ /\[/' | ${AWK} -v sec=$sym_sec '$1 == "[" sec "]" { print "0x" $6; exit }') if [[ -z $sec_size ]]; then @@ -154,8 +161,7 @@ __faddr2line() { fi # Get the section name: - sec_name=$(${READELF} --section-headers --wide $objfile | - sed 's/\[ /\[/' | + sec_name=$(echo "${ELF_SECHEADERS}" | sed 's/\[ /\[/' | ${AWK} -v sec=$sym_sec '$1 == "[" sec "]" { print $2; exit }') if [[ -z $sec_name ]]; then @@ -197,7 +203,7 @@ __faddr2line() { found=2 break fi - done < <(${READELF} --symbols --wide $objfile | sed 's/\[.*\]//' | ${AWK} -v sec=$sym_sec '$7 == sec' | sort --key=2) + done < <(echo "${ELF_SYMS}" | sed 's/\[.*\]//' | ${AWK} -v sec=$sym_sec '$7 == sec' | sort --key=2) if [[ $found = 0 ]]; then warn "can't find symbol: sym_name: $sym_name sym_sec: $sym_sec sym_addr: $sym_addr sym_elf_size: $sym_elf_size" @@ -278,7 +284,7 @@ __faddr2line() { DONE=1 - done < <(${READELF} --symbols --wide $objfile | sed 's/\[.*\]//' | ${AWK} -v fn=$sym_name '$8 == fn') + done < <(echo "${ELF_SYMS}" | sed 's/\[.*\]//' | ${AWK} -v fn=$sym_name '$8 == fn') } [[ $# -lt 2 ]] && usage @@ -291,7 +297,9 @@ LIST=0 [[ ! -f $objfile ]] && die "can't find objfile $objfile" shift -${READELF} --section-headers --wide $objfile | ${GREP} -q '\.debug_info' || die "CONFIG_DEBUG_INFO not enabled" +run_readelf $objfile + +echo "${ELF_SECHEADERS}" | ${GREP} -q '\.debug_info' || die "CONFIG_DEBUG_INFO not enabled" DIR_PREFIX=supercalifragilisticexpialidocious find_dir_prefix $objfile |