67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 1) #!/bin/bash
b24413180f560 (Greg Kroah-Hartman 2017-11-01 15:07:57 +0100 2) # SPDX-License-Identifier: GPL-2.0
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 3) #
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 4) # Translate stack dump function offsets.
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 5) #
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 6) # addr2line doesn't work with KASLR addresses. This works similarly to
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 7) # addr2line, but instead takes the 'func+0x123' format as input:
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 8) #
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 9) # $ ./scripts/faddr2line ~/k/vmlinux meminfo_proc_show+0x5/0x568
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 10) # meminfo_proc_show+0x5/0x568:
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 11) # meminfo_proc_show at fs/proc/meminfo.c:27
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 12) #
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 13) # If the address is part of an inlined function, the full inline call chain is
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 14) # printed:
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 15) #
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 16) # $ ./scripts/faddr2line ~/k/vmlinux native_write_msr+0x6/0x27
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 17) # native_write_msr+0x6/0x27:
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 18) # arch_static_branch at arch/x86/include/asm/msr.h:121
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 19) # (inlined by) static_key_false at include/linux/jump_label.h:125
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 20) # (inlined by) native_write_msr at arch/x86/include/asm/msr.h:125
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 21) #
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 22) # The function size after the '/' in the input is optional, but recommended.
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 23) # It's used to help disambiguate any duplicate symbol names, which can occur
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 24) # rarely. If the size is omitted for a duplicate symbol then it's possible for
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 25) # multiple code sites to be printed:
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 26) #
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 27) # $ ./scripts/faddr2line ~/k/vmlinux raw_ioctl+0x5
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 28) # raw_ioctl+0x5/0x20:
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 29) # raw_ioctl at drivers/char/raw.c:122
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 30) #
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 31) # raw_ioctl+0x5/0xb1:
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 32) # raw_ioctl at net/ipv4/raw.c:876
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 33) #
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 34) # Multiple addresses can be specified on a single command line:
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 35) #
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 36) # $ ./scripts/faddr2line ~/k/vmlinux type_show+0x10/45 free_reserved_area+0x90
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 37) # type_show+0x10/0x2d:
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 38) # type_show at drivers/video/backlight/backlight.c:213
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 39) #
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 40) # free_reserved_area+0x90/0x123:
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 41) # free_reserved_area at mm/page_alloc.c:6429 (discriminator 2)
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 42)
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 43)
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 44) set -o errexit
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 45) set -o nounset
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 46)
4cc90b4cc3d49 (Liu, Changcheng 2017-12-14 15:32:48 -0800 47) READELF="${CROSS_COMPILE:-}readelf"
4cc90b4cc3d49 (Liu, Changcheng 2017-12-14 15:32:48 -0800 48) ADDR2LINE="${CROSS_COMPILE:-}addr2line"
4cc90b4cc3d49 (Liu, Changcheng 2017-12-14 15:32:48 -0800 49) SIZE="${CROSS_COMPILE:-}size"
4cc90b4cc3d49 (Liu, Changcheng 2017-12-14 15:32:48 -0800 50) NM="${CROSS_COMPILE:-}nm"
95a8798254193 (Liu, Changcheng 2017-11-29 16:10:25 -0800 51)
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 52) command -v awk >/dev/null 2>&1 || die "awk isn't installed"
95a8798254193 (Liu, Changcheng 2017-11-29 16:10:25 -0800 53) command -v ${READELF} >/dev/null 2>&1 || die "readelf isn't installed"
95a8798254193 (Liu, Changcheng 2017-11-29 16:10:25 -0800 54) command -v ${ADDR2LINE} >/dev/null 2>&1 || die "addr2line isn't installed"
95a8798254193 (Liu, Changcheng 2017-11-29 16:10:25 -0800 55) command -v ${SIZE} >/dev/null 2>&1 || die "size isn't installed"
95a8798254193 (Liu, Changcheng 2017-11-29 16:10:25 -0800 56) command -v ${NM} >/dev/null 2>&1 || die "nm isn't installed"
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 57)
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 58) usage() {
689135f0ed61b (Peter Zijlstra (Intel) 2018-06-04 13:48:31 -0500 59) echo "usage: faddr2line [--list] <object file> <func+offset> <func+offset>..." >&2
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 60) exit 1
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 61) }
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 62)
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 63) warn() {
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 64) echo "$1" >&2
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 65) }
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 66)
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 67) die() {
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 68) echo "ERROR: $1" >&2
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 69) exit 1
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 70) }
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 71)
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 72) # Try to figure out the source directory prefix so we can remove it from the
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 73) # addr2line output. HACK ALERT: This assumes that start_kernel() is in
f5f67cc0e0d3d (Randy Dunlap 2018-11-16 15:08:22 -0800 74) # init/main.c! This only works for vmlinux. Otherwise it falls back to
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 75) # printing the absolute path.
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 76) find_dir_prefix() {
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 77) local objfile=$1
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 78)
95a8798254193 (Liu, Changcheng 2017-11-29 16:10:25 -0800 79) local start_kernel_addr=$(${READELF} -sW $objfile | awk '$8 == "start_kernel" {printf "0x%s", $2}')
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 80) [[ -z $start_kernel_addr ]] && return
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 81)
95a8798254193 (Liu, Changcheng 2017-11-29 16:10:25 -0800 82) local file_line=$(${ADDR2LINE} -e $objfile $start_kernel_addr)
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 83) [[ -z $file_line ]] && return
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 84)
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 85) local prefix=${file_line%init/main.c:*}
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 86) if [[ -z $prefix ]] || [[ $prefix = $file_line ]]; then
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 87) return
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 88) fi
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 89)
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 90) DIR_PREFIX=$prefix
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 91) return 0
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 92) }
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 93)
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 94) __faddr2line() {
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 95) local objfile=$1
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 96) local func_addr=$2
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 97) local dir_prefix=$3
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 98) local print_warnings=$4
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 99)
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 100) local func=${func_addr%+*}
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 101) local offset=${func_addr#*+}
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 102) offset=${offset%/*}
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 103) local size=
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 104) [[ $func_addr =~ "/" ]] && size=${func_addr#*/}
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 105)
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 106) if [[ -z $func ]] || [[ -z $offset ]] || [[ $func = $func_addr ]]; then
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 107) warn "bad func+offset $func_addr"
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 108) DONE=1
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 109) return
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 110) fi
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 111)
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 112) # Go through each of the object's symbols which match the func name.
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 113) # In rare cases there might be duplicates.
95a8798254193 (Liu, Changcheng 2017-11-29 16:10:25 -0800 114) file_end=$(${SIZE} -Ax $objfile | awk '$1 == ".text" {print $2}')
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 115) while read symbol; do
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 116) local fields=($symbol)
efdb4167e676a (Josh Poimboeuf 2016-10-25 09:51:11 -0500 117) local sym_base=0x${fields[0]}
efdb4167e676a (Josh Poimboeuf 2016-10-25 09:51:11 -0500 118) local sym_type=${fields[1]}
2aab9c3ca47dd (NeilBrown 2017-10-12 14:22:04 +1100 119) local sym_end=${fields[3]}
efdb4167e676a (Josh Poimboeuf 2016-10-25 09:51:11 -0500 120)
efdb4167e676a (Josh Poimboeuf 2016-10-25 09:51:11 -0500 121) # calculate the size
efdb4167e676a (Josh Poimboeuf 2016-10-25 09:51:11 -0500 122) local sym_size=$(($sym_end - $sym_base))
efdb4167e676a (Josh Poimboeuf 2016-10-25 09:51:11 -0500 123) if [[ -z $sym_size ]] || [[ $sym_size -le 0 ]]; then
efdb4167e676a (Josh Poimboeuf 2016-10-25 09:51:11 -0500 124) warn "bad symbol size: base: $sym_base end: $sym_end"
efdb4167e676a (Josh Poimboeuf 2016-10-25 09:51:11 -0500 125) DONE=1
efdb4167e676a (Josh Poimboeuf 2016-10-25 09:51:11 -0500 126) return
efdb4167e676a (Josh Poimboeuf 2016-10-25 09:51:11 -0500 127) fi
efdb4167e676a (Josh Poimboeuf 2016-10-25 09:51:11 -0500 128) sym_size=0x$(printf %x $sym_size)
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 129)
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 130) # calculate the address
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 131) local addr=$(($sym_base + $offset))
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 132) if [[ -z $addr ]] || [[ $addr = 0 ]]; then
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 133) warn "bad address: $sym_base + $offset"
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 134) DONE=1
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 135) return
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 136) fi
efdb4167e676a (Josh Poimboeuf 2016-10-25 09:51:11 -0500 137) addr=0x$(printf %x $addr)
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 138)
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 139) # weed out non-function symbols
efdb4167e676a (Josh Poimboeuf 2016-10-25 09:51:11 -0500 140) if [[ $sym_type != t ]] && [[ $sym_type != T ]]; then
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 141) [[ $print_warnings = 1 ]] &&
efdb4167e676a (Josh Poimboeuf 2016-10-25 09:51:11 -0500 142) echo "skipping $func address at $addr due to non-function symbol of type '$sym_type'"
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 143) continue
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 144) fi
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 145)
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 146) # if the user provided a size, make sure it matches the symbol's size
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 147) if [[ -n $size ]] && [[ $size -ne $sym_size ]]; then
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 148) [[ $print_warnings = 1 ]] &&
efdb4167e676a (Josh Poimboeuf 2016-10-25 09:51:11 -0500 149) echo "skipping $func address at $addr due to size mismatch ($size != $sym_size)"
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 150) continue;
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 151) fi
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 152)
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 153) # make sure the provided offset is within the symbol's range
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 154) if [[ $offset -gt $sym_size ]]; then
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 155) [[ $print_warnings = 1 ]] &&
efdb4167e676a (Josh Poimboeuf 2016-10-25 09:51:11 -0500 156) echo "skipping $func address at $addr due to size mismatch ($offset > $sym_size)"
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 157) continue
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 158) fi
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 159)
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 160) # separate multiple entries with a blank line
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 161) [[ $FIRST = 0 ]] && echo
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 162) FIRST=0
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 163)
efdb4167e676a (Josh Poimboeuf 2016-10-25 09:51:11 -0500 164) # pass real address to addr2line
efdb4167e676a (Josh Poimboeuf 2016-10-25 09:51:11 -0500 165) echo "$func+$offset/$sym_size:"
6870c0165feaa (Changbin Du 2018-04-05 16:18:29 -0700 166) local file_lines=$(${ADDR2LINE} -fpie $objfile $addr | sed "s; $dir_prefix\(\./\)*; ;")
6870c0165feaa (Changbin Du 2018-04-05 16:18:29 -0700 167) [[ -z $file_lines ]] && return
6870c0165feaa (Changbin Du 2018-04-05 16:18:29 -0700 168)
689135f0ed61b (Peter Zijlstra (Intel) 2018-06-04 13:48:31 -0500 169) if [[ $LIST = 0 ]]; then
689135f0ed61b (Peter Zijlstra (Intel) 2018-06-04 13:48:31 -0500 170) echo "$file_lines" | while read -r line
689135f0ed61b (Peter Zijlstra (Intel) 2018-06-04 13:48:31 -0500 171) do
689135f0ed61b (Peter Zijlstra (Intel) 2018-06-04 13:48:31 -0500 172) echo $line
689135f0ed61b (Peter Zijlstra (Intel) 2018-06-04 13:48:31 -0500 173) done
689135f0ed61b (Peter Zijlstra (Intel) 2018-06-04 13:48:31 -0500 174) DONE=1;
689135f0ed61b (Peter Zijlstra (Intel) 2018-06-04 13:48:31 -0500 175) return
689135f0ed61b (Peter Zijlstra (Intel) 2018-06-04 13:48:31 -0500 176) fi
689135f0ed61b (Peter Zijlstra (Intel) 2018-06-04 13:48:31 -0500 177)
6870c0165feaa (Changbin Du 2018-04-05 16:18:29 -0700 178) # show each line with context
6870c0165feaa (Changbin Du 2018-04-05 16:18:29 -0700 179) echo "$file_lines" | while read -r line
6870c0165feaa (Changbin Du 2018-04-05 16:18:29 -0700 180) do
689135f0ed61b (Peter Zijlstra (Intel) 2018-06-04 13:48:31 -0500 181) echo
6870c0165feaa (Changbin Du 2018-04-05 16:18:29 -0700 182) echo $line
78eb0c6356cda (Changbin Du 2018-05-11 16:02:11 -0700 183) n=$(echo $line | sed 's/.*:\([0-9]\+\).*/\1/g')
78eb0c6356cda (Changbin Du 2018-05-11 16:02:11 -0700 184) n1=$[$n-5]
78eb0c6356cda (Changbin Du 2018-05-11 16:02:11 -0700 185) n2=$[$n+5]
78eb0c6356cda (Changbin Du 2018-05-11 16:02:11 -0700 186) f=$(echo $line | sed 's/.*at \(.\+\):.*/\1/g')
689135f0ed61b (Peter Zijlstra (Intel) 2018-06-04 13:48:31 -0500 187) awk 'NR>=strtonum("'$n1'") && NR<=strtonum("'$n2'") { if (NR=='$n') printf(">%d<", NR); else printf(" %d ", NR); printf("\t%s\n", $0)}' $f
6870c0165feaa (Changbin Du 2018-04-05 16:18:29 -0700 188) done
6870c0165feaa (Changbin Du 2018-04-05 16:18:29 -0700 189)
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 190) DONE=1
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 191)
95a8798254193 (Liu, Changcheng 2017-11-29 16:10:25 -0800 192) done < <(${NM} -n $objfile | awk -v fn=$func -v end=$file_end '$3 == fn { found=1; line=$0; start=$1; next } found == 1 { found=0; print line, "0x"$1 } END {if (found == 1) print line, end; }')
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 193) }
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 194)
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 195) [[ $# -lt 2 ]] && usage
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 196)
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 197) objfile=$1
689135f0ed61b (Peter Zijlstra (Intel) 2018-06-04 13:48:31 -0500 198)
689135f0ed61b (Peter Zijlstra (Intel) 2018-06-04 13:48:31 -0500 199) LIST=0
689135f0ed61b (Peter Zijlstra (Intel) 2018-06-04 13:48:31 -0500 200) [[ "$objfile" == "--list" ]] && LIST=1 && shift && objfile=$1
689135f0ed61b (Peter Zijlstra (Intel) 2018-06-04 13:48:31 -0500 201)
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 202) [[ ! -f $objfile ]] && die "can't find objfile $objfile"
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 203) shift
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 204)
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 205) DIR_PREFIX=supercalifragilisticexpialidocious
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 206) find_dir_prefix $objfile
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 207)
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 208) FIRST=1
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 209) while [[ $# -gt 0 ]]; do
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 210) func_addr=$1
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 211) shift
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 212)
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 213) # print any matches found
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 214) DONE=0
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 215) __faddr2line $objfile $func_addr $DIR_PREFIX 0
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 216)
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 217) # if no match was found, print warnings
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 218) if [[ $DONE = 0 ]]; then
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 219) __faddr2line $objfile $func_addr $DIR_PREFIX 1
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 220) warn "no match for $func_addr"
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 221) fi
67326666e2d45 (Josh Poimboeuf 2016-09-19 10:52:14 -0500 222) done