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 | find_dir_prefix() { | 87 | find_dir_prefix() { |
| 88 | local objfile=$1 | 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 | ${AWK} '$8 == "start_kernel" {printf "0x%s", $2}') | 91 | ${AWK} '$8 == "start_kernel" {printf "0x%s", $2}') |
| 92 | [[ -z $start_kernel_addr ]] && return | 92 | [[ -z $start_kernel_addr ]] && return |
| 93 | 93 | ||
| @@ -103,6 +103,14 @@ find_dir_prefix() { · 9 unmodified lines | |||
| 103 | return 0 | 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 | __faddr2line() { | 114 | __faddr2line() { |
| 107 | local objfile=$1 | 115 | local objfile=$1 |
| 108 | local func_addr=$2 | 116 | local func_addr=$2 |
| @@ -125,7 +133,7 @@ __faddr2line() { · 16 unmodified lines | |||
| 125 | 133 | ||
| 126 | # vmlinux uses absolute addresses in the section table rather than | 134 | # vmlinux uses absolute addresses in the section table rather than |
| 127 | # section offsets. | 135 | # section offsets. |
| 128 | local file_type=$(${READELF} --file-header $objfile | | 136 | local file_type=$(echo "${ELF_FILEHEADER}" | |
| 129 | ${AWK} '$1 == "Type:" { print $2; exit }') | 137 | ${AWK} '$1 == "Type:" { print $2; exit }') |
| 130 | if [[ $file_type = "EXEC" ]] || [[ $file_type == "DYN" ]]; then | 138 | if [[ $file_type = "EXEC" ]] || [[ $file_type == "DYN" ]]; then |
| 131 | is_vmlinux=1 | 139 | is_vmlinux=1 |
| @@ -143,8 +151,7 @@ __faddr2line() { · 11 unmodified lines | |||
| 143 | local sec_name | 151 | local sec_name |
| 144 | 152 | ||
| 145 | # Get the section size: | 153 | # Get the section size: |
| 146 | sec_size=$(${READELF} --section-headers --wide $objfile | | 154 | sec_size=$(echo "${ELF_SECHEADERS}" | sed 's/\[ /\[/' | |
| 147 | sed 's/\[ /\[/' | | ||
| 148 | ${AWK} -v sec=$sym_sec '$1 == "[" sec "]" { print "0x" $6; exit }') | 155 | ${AWK} -v sec=$sym_sec '$1 == "[" sec "]" { print "0x" $6; exit }') |
| 149 | 156 | ||
| 150 | if [[ -z $sec_size ]]; then | 157 | if [[ -z $sec_size ]]; then |
| @@ -154,8 +161,7 @@ __faddr2line() { · 3 unmodified lines | |||
| 154 | fi | 161 | fi |
| 155 | 162 | ||
| 156 | # Get the section name: | 163 | # Get the section name: |
| 157 | sec_name=$(${READELF} --section-headers --wide $objfile | | 164 | sec_name=$(echo "${ELF_SECHEADERS}" | sed 's/\[ /\[/' | |
| 158 | sed 's/\[ /\[/' | | ||
| 159 | ${AWK} -v sec=$sym_sec '$1 == "[" sec "]" { print $2; exit }') | 165 | ${AWK} -v sec=$sym_sec '$1 == "[" sec "]" { print $2; exit }') |
| 160 | 166 | ||
| 161 | if [[ -z $sec_name ]]; then | 167 | if [[ -z $sec_name ]]; then |
| @@ -197,7 +203,7 @@ __faddr2line() { · 35 unmodified lines | |||
| 197 | found=2 | 203 | found=2 |
| 198 | break | 204 | break |
| 199 | fi | 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 | if [[ $found = 0 ]]; then | 208 | if [[ $found = 0 ]]; then |
| 203 | warn "can't find symbol: sym_name: $sym_name sym_sec: $sym_sec sym_addr: $sym_addr sym_elf_size: $sym_elf_size" | 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 | DONE=1 | 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 | [[ $# -lt 2 ]] && usage | 290 | [[ $# -lt 2 ]] && usage |
| @@ -291,7 +297,9 @@ LIST=0 · 6 unmodified lines | |||
| 291 | [[ ! -f $objfile ]] && die "can't find objfile $objfile" | 297 | [[ ! -f $objfile ]] && die "can't find objfile $objfile" |
| 292 | shift | 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 | DIR_PREFIX=supercalifragilisticexpialidocious | 304 | DIR_PREFIX=supercalifragilisticexpialidocious |
| 297 | find_dir_prefix $objfile | 305 | find_dir_prefix $objfile |