From 4ea80652dc75482dca1739762075dd5caa57ae29 Mon Sep 17 00:00:00 2001 From: Nicholas Piggin Date: Fri, 12 May 2017 03:40:38 +1000 Subject: [PATCH] powerpc/64s: Tool to flag direct branches from unrelocated interrupt vectors Direct banches from code below __end_interrupts to code above __end_interrupts when built with CONFIG_RELOCATABLE are disallowed because they will break when the kernel is not located at 0. Sample output: WARNING: Unrelocated relative branches c000000000000118 bl-> 0xc000000000038fb8 c00000000000013c b-> 0xc0000000001068a4 c000000000000148 b-> 0xc00000000003919c c00000000000014c b-> 0xc00000000003923c c0000000000005a4 b-> 0xc000000000106ffc c000000000001af0 b-> 0xc000000000106ffc c000000000001b24 b-> 0xc000000000106ffc c000000000001b58 b-> 0xc000000000106ffc Signed-off-by: Balbir Singh Signed-off-by: Nicholas Piggin Signed-off-by: Michael Ellerman --- arch/powerpc/Makefile.postlink | 9 +++- arch/powerpc/tools/unrel_branch_check.sh | 57 ++++++++++++++++++++++++ 2 files changed, 65 insertions(+), 1 deletion(-) create mode 100755 arch/powerpc/tools/unrel_branch_check.sh diff --git a/arch/powerpc/Makefile.postlink b/arch/powerpc/Makefile.postlink index eccfcc88afae..50336930e6f7 100644 --- a/arch/powerpc/Makefile.postlink +++ b/arch/powerpc/Makefile.postlink @@ -11,7 +11,14 @@ __archpost: include scripts/Kbuild.include quiet_cmd_relocs_check = CHKREL $@ - cmd_relocs_check = $(CONFIG_SHELL) $(srctree)/arch/powerpc/tools/relocs_check.sh "$(OBJDUMP)" "$@" +ifdef CONFIG_PPC_BOOK3S_64 + cmd_relocs_check = \ + $(CONFIG_SHELL) $(srctree)/arch/powerpc/tools/relocs_check.sh "$(OBJDUMP)" "$@" ; \ + $(CONFIG_SHELL) $(srctree)/arch/powerpc/tools/unrel_branch_check.sh "$(OBJDUMP)" "$@" +else + cmd_relocs_check = \ + $(CONFIG_SHELL) $(srctree)/arch/powerpc/tools/relocs_check.sh "$(OBJDUMP)" "$@" +endif # `@true` prevents complaint when there is nothing to be done diff --git a/arch/powerpc/tools/unrel_branch_check.sh b/arch/powerpc/tools/unrel_branch_check.sh new file mode 100755 index 000000000000..1e972df3107e --- /dev/null +++ b/arch/powerpc/tools/unrel_branch_check.sh @@ -0,0 +1,57 @@ +# Copyright © 2016 IBM Corporation +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version +# 2 of the License, or (at your option) any later version. +# +# This script checks the relocations of a vmlinux for "suspicious" +# branches from unrelocated code (head_64.S code). + +# Turn this on if you want more debug output: +# set -x + +# Have Kbuild supply the path to objdump so we handle cross compilation. +objdump="$1" +vmlinux="$2" + +#__end_interrupts should be located within the first 64K + +end_intr=0x$( +"$objdump" -R "$vmlinux" -d --start-address=0xc000000000000000 \ + --stop-address=0xc000000000010000 | +grep '\<__end_interrupts>:' | +awk '{print $1}' +) + +BRANCHES=$( +"$objdump" -R "$vmlinux" -D --start-address=0xc000000000000000 \ + --stop-address=${end_intr} | +grep -e "^c[0-9a-f]*:[[:space:]]*\([0-9a-f][0-9a-f][[:space:]]\)\{4\}[[:space:]]*b" | +grep -v '\<__start_initialization_multiplatform>' | +grep -v -e 'b.\?.\?ctr' | +grep -v -e 'b.\?.\?lr' | +sed 's/://' | +awk '{ print $1 ":" $6 ":0x" $7 ":" $8 " "}' +) + +for tuple in $BRANCHES +do + from=`echo $tuple | cut -d':' -f1` + branch=`echo $tuple | cut -d':' -f2` + to=`echo $tuple | cut -d':' -f3 | sed 's/cr[0-7],//'` + sym=`echo $tuple | cut -d':' -f4` + + if (( $to > $end_intr )) + then + if [ -z "$bad_branches" ]; then + echo "WARNING: Unrelocated relative branches" + bad_branches="yes" + fi + echo "$from $branch-> $to $sym" + fi +done + +if [ -z "$bad_branches" ]; then + exit 0 +fi -- 2.20.1