0001
0002
0003
0004
0005
0006
0007
0008
0009 objdump="$1"
0010 nm="$2"
0011 vmlinux="$3"
0012
0013 kstart=0xc000000000000000
0014
0015 end_intr=0x$($nm -p "$vmlinux" |
0016 sed -E -n '/\s+[[:alpha:]]\s+__end_interrupts\s*$/{s///p;q}')
0017 if [ "$end_intr" = "0x" ]; then
0018 exit 0
0019 fi
0020
0021
0022
0023
0024 sim=0x$($nm -p "$vmlinux" |
0025 sed -E -n '/\s+[[:alpha:]]\s+__start_initialization_multiplatform\s*$/{s///p;q}')
0026
0027 $objdump -D --no-show-raw-insn --start-address="$kstart" --stop-address="$end_intr" "$vmlinux" |
0028 sed -E -n '
0029 # match lines that start with a kernel address
0030 /^c[0-9a-f]*:\s*b/ {
0031 # drop branches via ctr or lr
0032 /\<b.?.?(ct|l)r/d
0033 # cope with some differences between Clang and GNU objdumps
0034 s/\<bt.?\s*[[:digit:]]+,/beq/
0035 s/\<bf.?\s*[[:digit:]]+,/bne/
0036 # tidy up
0037 s/\s0x/ /
0038 s/://
0039 # format for the loop below
0040 s/^(\S+)\s+(\S+)\s+(\S+)\s*(\S*).*$/\1:\2:\3:\4/
0041 # strip out condition registers
0042 s/:cr[0-7],/:/
0043 p
0044 }' | {
0045
0046 all_good=true
0047 while IFS=: read -r from branch to sym; do
0048 case "$to" in
0049 c*) to="0x$to"
0050 ;;
0051 .+*)
0052 to=${to
0053 if [ "$branch" = 'b' ]; then
0054 if (( to >= 0x2000000 )); then
0055 to=$(( to - 0x4000000 ))
0056 fi
0057 elif (( to >= 0x8000 )); then
0058 to=$(( to - 0x10000 ))
0059 fi
0060 printf -v to '0x%x' $(( "0x$from" + to ))
0061 ;;
0062 *) printf 'Unkown branch format\n'
0063 ;;
0064 esac
0065 if [ "$to" = "$sim" ]; then
0066 continue
0067 fi
0068 if (( to > end_intr )); then
0069 if $all_good; then
0070 printf '%s\n' 'WARNING: Unrelocated relative branches'
0071 all_good=false
0072 fi
0073 printf '%s %s-> %s %s\n' "$from" "$branch" "$to" "$sym"
0074 fi
0075 done
0076
0077 $all_good
0078
0079 }