1d9de6b0dSStephen Rothwell#!/bin/bash 23745ae63SStephen Rothwell# SPDX-License-Identifier: GPL-2.0+ 33745ae63SStephen Rothwell# Copyright © 2016,2020 IBM Corporation 44ea80652SNicholas Piggin# 53745ae63SStephen Rothwell# This script checks the unrelocated code of a vmlinux for "suspicious" 63745ae63SStephen Rothwell# branches to relocated code (head_64.S code). 74ea80652SNicholas Piggin 8b71dca98SStephen Rothwell# Have Kbuild supply the path to objdump and nm so we handle cross compilation. 94ea80652SNicholas Pigginobjdump="$1" 10b71dca98SStephen Rothwellnm="$2" 11b71dca98SStephen Rothwellvmlinux="$3" 124ea80652SNicholas Piggin 1320ff8ec1SStephen Rothwellkstart=0xc000000000000000 144ea80652SNicholas Piggin 15b71dca98SStephen Rothwellend_intr=0x$($nm -p "$vmlinux" | 16b71dca98SStephen Rothwell sed -E -n '/\s+[[:alpha:]]\s+__end_interrupts\s*$/{s///p;q}') 17af13a224SStephen Rothwellif [ "$end_intr" = "0x" ]; then 18af13a224SStephen Rothwell exit 0 19af13a224SStephen Rothwellfi 204ea80652SNicholas Piggin 21*6b1992bcSStephen Rothwell# we know that there is a correct branch to 22*6b1992bcSStephen Rothwell# __start_initialization_multiplatform, so find its address 23*6b1992bcSStephen Rothwell# so we can exclude it. 24*6b1992bcSStephen Rothwellsim=0x$($nm -p "$vmlinux" | 25*6b1992bcSStephen Rothwell sed -E -n '/\s+[[:alpha:]]\s+__start_initialization_multiplatform\s*$/{s///p;q}') 26*6b1992bcSStephen Rothwell 27*6b1992bcSStephen Rothwell$objdump -D --no-show-raw-insn --start-address="$kstart" --stop-address="$end_intr" "$vmlinux" | 283d97abbcSStephen Rothwellsed -E -n ' 293d97abbcSStephen Rothwell# match lines that start with a kernel address 303d97abbcSStephen Rothwell/^c[0-9a-f]*:\s*b/ { 313d97abbcSStephen Rothwell # drop branches via ctr or lr 323d97abbcSStephen Rothwell /\<b.?.?(ct|l)r/d 333d97abbcSStephen Rothwell # cope with some differences between Clang and GNU objdumps 343d97abbcSStephen Rothwell s/\<bt.?\s*[[:digit:]]+,/beq/ 353d97abbcSStephen Rothwell s/\<bf.?\s*[[:digit:]]+,/bne/ 363d97abbcSStephen Rothwell # tidy up 373d97abbcSStephen Rothwell s/\s0x/ / 383d97abbcSStephen Rothwell s/:// 393d97abbcSStephen Rothwell # format for the loop below 40*6b1992bcSStephen Rothwell s/^(\S+)\s+(\S+)\s+(\S+)\s*(\S*).*$/\1:\2:\3:\4/ 413d97abbcSStephen Rothwell # strip out condition registers 42*6b1992bcSStephen Rothwell s/:cr[0-7],/:/ 433d97abbcSStephen Rothwell p 44b84eaab6SStephen Rothwell}' | { 454ea80652SNicholas Piggin 46b84eaab6SStephen Rothwellall_good=true 47b84eaab6SStephen Rothwellwhile IFS=: read -r from branch to sym; do 48*6b1992bcSStephen Rothwell case "$to" in 49*6b1992bcSStephen Rothwell c*) to="0x$to" 50*6b1992bcSStephen Rothwell ;; 51*6b1992bcSStephen Rothwell .+*) 52*6b1992bcSStephen Rothwell to=${to#.+} 53*6b1992bcSStephen Rothwell if [ "$branch" = 'b' ]; then 54*6b1992bcSStephen Rothwell if (( to >= 0x2000000 )); then 55*6b1992bcSStephen Rothwell to=$(( to - 0x4000000 )) 56*6b1992bcSStephen Rothwell fi 57*6b1992bcSStephen Rothwell elif (( to >= 0x8000 )); then 58*6b1992bcSStephen Rothwell to=$(( to - 0x10000 )) 59*6b1992bcSStephen Rothwell fi 60*6b1992bcSStephen Rothwell printf -v to '0x%x' $(( "0x$from" + to )) 61*6b1992bcSStephen Rothwell ;; 62*6b1992bcSStephen Rothwell *) printf 'Unkown branch format\n' 63*6b1992bcSStephen Rothwell ;; 64*6b1992bcSStephen Rothwell esac 65*6b1992bcSStephen Rothwell if [ "$to" = "$sim" ]; then 66*6b1992bcSStephen Rothwell continue 67*6b1992bcSStephen Rothwell fi 6820ff8ec1SStephen Rothwell if (( to > end_intr )); then 69b84eaab6SStephen Rothwell if $all_good; then 70b84eaab6SStephen Rothwell printf '%s\n' 'WARNING: Unrelocated relative branches' 71b84eaab6SStephen Rothwell all_good=false 724ea80652SNicholas Piggin fi 73b84eaab6SStephen Rothwell printf '%s %s-> %s %s\n' "$from" "$branch" "$to" "$sym" 744ea80652SNicholas Piggin fi 754ea80652SNicholas Piggindone 764ea80652SNicholas Piggin 77b84eaab6SStephen Rothwell$all_good 78b84eaab6SStephen Rothwell 79b84eaab6SStephen Rothwell} 80