unrel_branch_check.sh (1880B)
1#!/bin/bash 2# SPDX-License-Identifier: GPL-2.0+ 3# Copyright © 2016,2020 IBM Corporation 4# 5# This script checks the unrelocated code of a vmlinux for "suspicious" 6# branches to relocated code (head_64.S code). 7 8# Have Kbuild supply the path to objdump and nm so we handle cross compilation. 9objdump="$1" 10nm="$2" 11vmlinux="$3" 12 13kstart=0xc000000000000000 14 15end_intr=0x$($nm -p "$vmlinux" | 16 sed -E -n '/\s+[[:alpha:]]\s+__end_interrupts\s*$/{s///p;q}') 17if [ "$end_intr" = "0x" ]; then 18 exit 0 19fi 20 21# we know that there is a correct branch to 22# __start_initialization_multiplatform, so find its address 23# so we can exclude it. 24sim=0x$($nm -p "$vmlinux" | 25 sed -E -n '/\s+[[:alpha:]]\s+__start_initialization_multiplatform\s*$/{s///p;q}') 26 27$objdump -D --no-show-raw-insn --start-address="$kstart" --stop-address="$end_intr" "$vmlinux" | 28sed -E -n ' 29# match lines that start with a kernel address 30/^c[0-9a-f]*:\s*b/ { 31 # drop branches via ctr or lr 32 /\<b.?.?(ct|l)r/d 33 # cope with some differences between Clang and GNU objdumps 34 s/\<bt.?\s*[[:digit:]]+,/beq/ 35 s/\<bf.?\s*[[:digit:]]+,/bne/ 36 # tidy up 37 s/\s0x/ / 38 s/:// 39 # format for the loop below 40 s/^(\S+)\s+(\S+)\s+(\S+)\s*(\S*).*$/\1:\2:\3:\4/ 41 # strip out condition registers 42 s/:cr[0-7],/:/ 43 p 44}' | { 45 46all_good=true 47while IFS=: read -r from branch to sym; do 48 case "$to" in 49 c*) to="0x$to" 50 ;; 51 .+*) 52 to=${to#.+} 53 if [ "$branch" = 'b' ]; then 54 if (( to >= 0x2000000 )); then 55 to=$(( to - 0x4000000 )) 56 fi 57 elif (( to >= 0x8000 )); then 58 to=$(( to - 0x10000 )) 59 fi 60 printf -v to '0x%x' $(( "0x$from" + to )) 61 ;; 62 *) printf 'Unkown branch format\n' 63 ;; 64 esac 65 if [ "$to" = "$sim" ]; then 66 continue 67 fi 68 if (( to > end_intr )); then 69 if $all_good; then 70 printf '%s\n' 'WARNING: Unrelocated relative branches' 71 all_good=false 72 fi 73 printf '%s %s-> %s %s\n' "$from" "$branch" "$to" "$sym" 74 fi 75done 76 77$all_good 78 79}