| @@ -95,17 +95,25 @@ __faddr2line() { · 94 unmodified lines |
| 95 | local print_warnings=$4 | 95 | local print_warnings=$4 |
| 96 | | 96 | |
| 97 | local sym_name=${func_addr%+*} | 97 | local sym_name=${func_addr%+*} |
| 98 | local offset=${func_addr#*+} | 98 | local func_offset=${func_addr#*+} |
| 99 | offset=${offset%/*} | 99 | func_offset=${func_offset%/*} |
| 100 | local user_size= | 100 | local user_size= |
| | 101 | local file_type |
| | 102 | local is_vmlinux=0 |
| 101 | [[ $func_addr =~ "/" ]] && user_size=${func_addr#*/} | 103 | [[ $func_addr =~ "/" ]] && user_size=${func_addr#*/} |
| 102 | | 104 | |
| 103 | if [[ -z $sym_name ]] || [[ -z $offset ]] || [[ $sym_name = $func_addr ]]; then | 105 | if [[ -z $sym_name ]] || [[ -z $func_offset ]] || [[ $sym_name = $func_addr ]]; then |
| 104 | warn "bad func+offset $func_addr" | 106 | warn "bad func+offset $func_addr" |
| 105 | DONE=1 | 107 | DONE=1 |
| 106 | return | 108 | return |
| 107 | fi | 109 | fi |
| 108 | | 110 | |
| | 111 | # vmlinux uses absolute addresses in the section table rather than |
| | 112 | # section offsets. |
| | 113 | local file_type=$(${READELF} --file-header $objfile | |
| | 114 | ${AWK} '$1 == "Type:" { print $2; exit }') |
| | 115 | [[ $file_type = "EXEC" ]] && is_vmlinux=1 |
| | 116 | |
| 109 | # Go through each of the object's symbols which match the func name. | 117 | # Go through each of the object's symbols which match the func name. |
| 110 | # In rare cases there might be duplicates, in which case we print all | 118 | # In rare cases there might be duplicates, in which case we print all |
| 111 | # matches. | 119 | # matches. |
| @@ -114,9 +122,11 @@ __faddr2line() { · 2 unmodified lines |
| 114 | local sym_addr=0x${fields[1]} | 122 | local sym_addr=0x${fields[1]} |
| 115 | local sym_elf_size=${fields[2]} | 123 | local sym_elf_size=${fields[2]} |
| 116 | local sym_sec=${fields[6]} | 124 | local sym_sec=${fields[6]} |
| | 125 | local sec_size |
| | 126 | local sec_name |
| 117 | | 127 | |
| 118 | # Get the section size: | 128 | # Get the section size: |
| 119 | local sec_size=$(${READELF} --section-headers --wide $objfile | | 129 | sec_size=$(${READELF} --section-headers --wide $objfile | |
| 120 | sed 's/\[ /\[/' | | 130 | sed 's/\[ /\[/' | |
| 121 | ${AWK} -v sec=$sym_sec '$1 == "[" sec "]" { print "0x" $6; exit }') | 131 | ${AWK} -v sec=$sym_sec '$1 == "[" sec "]" { print "0x" $6; exit }') |
| 122 | | 132 | |
| @@ -126,6 +136,17 @@ __faddr2line() { · 3 unmodified lines |
| 126 | return | 136 | return |
| 127 | fi | 137 | fi |
| 128 | | 138 | |
| | 139 | # Get the section name: |
| | 140 | sec_name=$(${READELF} --section-headers --wide $objfile | |
| | 141 | sed 's/\[ /\[/' | |
| | 142 | ${AWK} -v sec=$sym_sec '$1 == "[" sec "]" { print $2; exit }') |
| | 143 | |
| | 144 | if [[ -z $sec_name ]]; then |
| | 145 | warn "bad section name: section: $sym_sec" |
| | 146 | DONE=1 |
| | 147 | return |
| | 148 | fi |
| | 149 | |
| 129 | # Calculate the symbol size. | 150 | # Calculate the symbol size. |
| 130 | # | 151 | # |
| 131 | # Unfortunately we can't use the ELF size, because kallsyms | 152 | # Unfortunately we can't use the ELF size, because kallsyms |
| @@ -174,10 +195,10 @@ __faddr2line() { · 42 unmodified lines |
| 174 | | 195 | |
| 175 | sym_size=0x$(printf %x $sym_size) | 196 | sym_size=0x$(printf %x $sym_size) |
| 176 | | 197 | |
| 177 | # Calculate the section address from user-supplied offset: | 198 | # Calculate the address from user-supplied offset: |
| 178 | local addr=$(($sym_addr + $offset)) | 199 | local addr=$(($sym_addr + $func_offset)) |
| 179 | if [[ -z $addr ]] || [[ $addr = 0 ]]; then | 200 | if [[ -z $addr ]] || [[ $addr = 0 ]]; then |
| 180 | warn "bad address: $sym_addr + $offset" | 201 | warn "bad address: $sym_addr + $func_offset" |
| 181 | DONE=1 | 202 | DONE=1 |
| 182 | return | 203 | return |
| 183 | fi | 204 | fi |
| @@ -191,9 +212,9 @@ __faddr2line() { · 7 unmodified lines |
| 191 | fi | 212 | fi |
| 192 | | 213 | |
| 193 | # Make sure the provided offset is within the symbol's range: | 214 | # Make sure the provided offset is within the symbol's range: |
| 194 | if [[ $offset -gt $sym_size ]]; then | 215 | if [[ $func_offset -gt $sym_size ]]; then |
| 195 | [[ $print_warnings = 1 ]] && | 216 | [[ $print_warnings = 1 ]] && |
| 196 | echo "skipping $sym_name address at $addr due to size mismatch ($offset > $sym_size)" | 217 | echo "skipping $sym_name address at $addr due to size mismatch ($func_offset > $sym_size)" |
| 197 | continue | 218 | continue |
| 198 | fi | 219 | fi |
| 199 | | 220 | |
| @@ -202,11 +223,13 @@ __faddr2line() { · 2 unmodified lines |
| 202 | [[ $FIRST = 0 ]] && echo | 223 | [[ $FIRST = 0 ]] && echo |
| 203 | FIRST=0 | 224 | FIRST=0 |
| 204 | | 225 | |
| 205 | echo "$sym_name+$offset/$sym_size:" | 226 | echo "$sym_name+$func_offset/$sym_size:" |
| 206 | | 227 | |
| 207 | # Pass section address to addr2line and strip absolute paths | 228 | # Pass section address to addr2line and strip absolute paths |
| 208 | # from the output: | 229 | # from the output: |
| 209 | local output=$(${ADDR2LINE} -fpie $objfile $addr | sed "s; $dir_prefix\(\./\)*; ;") | 230 | local args="--functions --pretty-print --inlines --exe=$objfile" |
| | 231 | [[ $is_vmlinux = 0 ]] && args="$args --section=$sec_name" |
| | 232 | local output=$(${ADDR2LINE} $args $addr | sed "s; $dir_prefix\(\./\)*; ;") |
| 210 | [[ -z $output ]] && continue | 233 | [[ -z $output ]] && continue |
| 211 | | 234 | |
| 212 | # Default output (non --list): | 235 | # Default output (non --list): |