powerpc: unrel_branch_check.sh: enable the use of llvm-objdump v9, 10 or 11

Currently, using llvm-objtool, this script just silently succeeds without
actually do the intended checking.  So this updates it to work properly.

Firstly, llvm-objdump does not add target symbol names to the end
of branches in its asm output, so we have to drop the branch to
__start_initialization_multiplatform using its address.

Secondly, v9 and 10 specify branch targets as .+<offset>, so we convert
those to actual addresses.

Thirdly, v10 and 11 error out on a vmlinux if given the -R option
complaining that it is "not a dynamic object".  The -R does not make
any difference to the asm output, so remove it.

Lastly, v11 produces asm that is very similar to Gnu objtool (at least
as far as branches are concerned), so no further changes are necessary
to make it work.

Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/20200812081036.7969-3-sfr@canb.auug.org.au
This commit is contained in:
Stephen Rothwell 2020-08-12 18:10:36 +10:00 committed by Michael Ellerman
parent b71dca9891
commit 6b1992bcde
1 changed files with 29 additions and 5 deletions

View File

@ -18,12 +18,16 @@ if [ "$end_intr" = "0x" ]; then
exit 0 exit 0
fi fi
$objdump -R -D --no-show-raw-insn --start-address="$kstart" --stop-address="$end_intr" "$vmlinux" | # we know that there is a correct branch to
# __start_initialization_multiplatform, so find its address
# so we can exclude it.
sim=0x$($nm -p "$vmlinux" |
sed -E -n '/\s+[[:alpha:]]\s+__start_initialization_multiplatform\s*$/{s///p;q}')
$objdump -D --no-show-raw-insn --start-address="$kstart" --stop-address="$end_intr" "$vmlinux" |
sed -E -n ' sed -E -n '
# match lines that start with a kernel address # match lines that start with a kernel address
/^c[0-9a-f]*:\s*b/ { /^c[0-9a-f]*:\s*b/ {
# drop a target that we do not care about
/\<__start_initialization_multiplatform>/d
# drop branches via ctr or lr # drop branches via ctr or lr
/\<b.?.?(ct|l)r/d /\<b.?.?(ct|l)r/d
# cope with some differences between Clang and GNU objdumps # cope with some differences between Clang and GNU objdumps
@ -33,14 +37,34 @@ sed -E -n '
s/\s0x/ / s/\s0x/ /
s/:// s/://
# format for the loop below # format for the loop below
s/^(\S+)\s+(\S+)\s+(\S+)\s*(\S*).*$/\1:\2:0x\3:\4/ s/^(\S+)\s+(\S+)\s+(\S+)\s*(\S*).*$/\1:\2:\3:\4/
# strip out condition registers # strip out condition registers
s/:0xcr[0-7],/:0x/ s/:cr[0-7],/:/
p p
}' | { }' | {
all_good=true all_good=true
while IFS=: read -r from branch to sym; do while IFS=: read -r from branch to sym; do
case "$to" in
c*) to="0x$to"
;;
.+*)
to=${to#.+}
if [ "$branch" = 'b' ]; then
if (( to >= 0x2000000 )); then
to=$(( to - 0x4000000 ))
fi
elif (( to >= 0x8000 )); then
to=$(( to - 0x10000 ))
fi
printf -v to '0x%x' $(( "0x$from" + to ))
;;
*) printf 'Unkown branch format\n'
;;
esac
if [ "$to" = "$sim" ]; then
continue
fi
if (( to > end_intr )); then if (( to > end_intr )); then
if $all_good; then if $all_good; then
printf '%s\n' 'WARNING: Unrelocated relative branches' printf '%s\n' 'WARNING: Unrelocated relative branches'