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.
Unified · Split
| @@ -87,7 +87,7 @@ command -v ${ADDR2LINE} >/dev/null 2>&1 || die "${ADDR2LINE} isn't installed" · 86 unmodified lines | ||
| 87 | 87 | find_dir_prefix() { |
| 88 | 88 | local objfile=$1 |
| 89 | 89 | |
| 90 | − local start_kernel_addr=$(${READELF} --symbols --wide $objfile | sed 's/\[.*\]//' | | |
| 90 | + local start_kernel_addr=$(echo "${ELF_SYMS}" | sed 's/\[.*\]//' | | |
| 91 | 91 | ${AWK} '$8 == "start_kernel" {printf "0x%s", $2}') |
| 92 | 92 | [[ -z $start_kernel_addr ]] && return |
| 93 | 93 | |
| @@ -103,6 +103,14 @@ find_dir_prefix() { · 9 unmodified lines | ||
| 103 | 103 | return 0 |
| 104 | 104 | } |
| 105 | 105 | |
| 106 | +run_readelf() { | |
| 107 | + local objfile=$1 | |
| 108 | + | |
| 109 | + ELF_FILEHEADER=$(${READELF} --file-header $objfile) | |
| 110 | + ELF_SECHEADERS=$(${READELF} --section-headers --wide $objfile) | |
| 111 | + ELF_SYMS=$(${READELF} --symbols --wide $objfile) | |
| 112 | +} | |
| 113 | + | |
| 106 | 114 | __faddr2line() { |
| 107 | 115 | local objfile=$1 |
| 108 | 116 | local func_addr=$2 |
| @@ -125,7 +133,7 @@ __faddr2line() { · 16 unmodified lines | ||
| 125 | 133 | |
| 126 | 134 | # vmlinux uses absolute addresses in the section table rather than |
| 127 | 135 | # section offsets. |
| 128 | − local file_type=$(${READELF} --file-header $objfile | | |
| 136 | + local file_type=$(echo "${ELF_FILEHEADER}" | | |
| 129 | 137 | ${AWK} '$1 == "Type:" { print $2; exit }') |
| 130 | 138 | if [[ $file_type = "EXEC" ]] || [[ $file_type == "DYN" ]]; then |
| 131 | 139 | is_vmlinux=1 |
| @@ -143,8 +151,7 @@ __faddr2line() { · 11 unmodified lines | ||
| 143 | 151 | local sec_name |
| 144 | 152 | |
| 145 | 153 | # Get the section size: |
| 146 | − sec_size=$(${READELF} --section-headers --wide $objfile | | |
| 147 | − sed 's/\[ /\[/' | | |
| 154 | + sec_size=$(echo "${ELF_SECHEADERS}" | sed 's/\[ /\[/' | | |
| 148 | 155 | ${AWK} -v sec=$sym_sec '$1 == "[" sec "]" { print "0x" $6; exit }') |
| 149 | 156 | |
| 150 | 157 | if [[ -z $sec_size ]]; then |
| @@ -154,8 +161,7 @@ __faddr2line() { · 3 unmodified lines | ||
| 154 | 161 | fi |
| 155 | 162 | |
| 156 | 163 | # Get the section name: |
| 157 | − sec_name=$(${READELF} --section-headers --wide $objfile | | |
| 158 | − sed 's/\[ /\[/' | | |
| 164 | + sec_name=$(echo "${ELF_SECHEADERS}" | sed 's/\[ /\[/' | | |
| 159 | 165 | ${AWK} -v sec=$sym_sec '$1 == "[" sec "]" { print $2; exit }') |
| 160 | 166 | |
| 161 | 167 | if [[ -z $sec_name ]]; then |
| @@ -197,7 +203,7 @@ __faddr2line() { · 35 unmodified lines | ||
| 197 | 203 | found=2 |
| 198 | 204 | break |
| 199 | 205 | fi |
| 200 | − done < <(${READELF} --symbols --wide $objfile | sed 's/\[.*\]//' | ${AWK} -v sec=$sym_sec '$7 == sec' | sort --key=2) | |
| 206 | + done < <(echo "${ELF_SYMS}" | sed 's/\[.*\]//' | ${AWK} -v sec=$sym_sec '$7 == sec' | sort --key=2) | |
| 201 | 207 | |
| 202 | 208 | if [[ $found = 0 ]]; then |
| 203 | 209 | 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() { · 74 unmodified lines | ||
| 278 | 284 | |
| 279 | 285 | DONE=1 |
| 280 | 286 | |
| 281 | − done < <(${READELF} --symbols --wide $objfile | sed 's/\[.*\]//' | ${AWK} -v fn=$sym_name '$8 == fn') | |
| 287 | + done < <(echo "${ELF_SYMS}" | sed 's/\[.*\]//' | ${AWK} -v fn=$sym_name '$8 == fn') | |
| 282 | 288 | } |
| 283 | 289 | |
| 284 | 290 | [[ $# -lt 2 ]] && usage |
| @@ -291,7 +297,9 @@ LIST=0 · 6 unmodified lines | ||
| 291 | 297 | [[ ! -f $objfile ]] && die "can't find objfile $objfile" |
| 292 | 298 | shift |
| 293 | 299 | |
| 294 | −${READELF} --section-headers --wide $objfile | ${GREP} -q '\.debug_info' || die "CONFIG_DEBUG_INFO not enabled" | |
| 300 | +run_readelf $objfile | |
| 301 | + | |
| 302 | +echo "${ELF_SECHEADERS}" | ${GREP} -q '\.debug_info' || die "CONFIG_DEBUG_INFO not enabled" | |
| 295 | 303 | |
| 296 | 304 | DIR_PREFIX=supercalifragilisticexpialidocious |
| 297 | 305 | find_dir_prefix $objfile |