Back to home page

OSCL-LXR

 
 

    


0001 #!/bin/bash
0002 # SPDX-License-Identifier: GPL-2.0+
0003 # Copyright © 2016,2020 IBM Corporation
0004 #
0005 # This script checks the unrelocated code of a vmlinux for "suspicious"
0006 # branches to relocated code (head_64.S code).
0007 
0008 # Have Kbuild supply the path to objdump and nm so we handle cross compilation.
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 # we know that there is a correct branch to
0022 # __start_initialization_multiplatform, so find its address
0023 # so we can exclude it.
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 }