162306a36Sopenharmony_ci#!/bin/bash 262306a36Sopenharmony_ci# SPDX-License-Identifier: GPL-2.0+ 362306a36Sopenharmony_ci# Copyright © 2016,2020 IBM Corporation 462306a36Sopenharmony_ci# 562306a36Sopenharmony_ci# This script checks the unrelocated code of a vmlinux for "suspicious" 662306a36Sopenharmony_ci# branches to relocated code (head_64.S code). 762306a36Sopenharmony_ci 862306a36Sopenharmony_ci# Have Kbuild supply the path to objdump and nm so we handle cross compilation. 962306a36Sopenharmony_ciobjdump="$1" 1062306a36Sopenharmony_cinm="$2" 1162306a36Sopenharmony_civmlinux="$3" 1262306a36Sopenharmony_ci 1362306a36Sopenharmony_cikstart=0xc000000000000000 1462306a36Sopenharmony_ci 1562306a36Sopenharmony_ciend_intr=0x$($nm -p "$vmlinux" | 1662306a36Sopenharmony_ci sed -E -n '/\s+[[:alpha:]]\s+__end_interrupts\s*$/{s///p;q}') 1762306a36Sopenharmony_ciif [ "$end_intr" = "0x" ]; then 1862306a36Sopenharmony_ci exit 0 1962306a36Sopenharmony_cifi 2062306a36Sopenharmony_ci 2162306a36Sopenharmony_ci# we know that there is a correct branch to 2262306a36Sopenharmony_ci# __start_initialization_multiplatform, so find its address 2362306a36Sopenharmony_ci# so we can exclude it. 2462306a36Sopenharmony_cisim=0x$($nm -p "$vmlinux" | 2562306a36Sopenharmony_ci sed -E -n '/\s+[[:alpha:]]\s+__start_initialization_multiplatform\s*$/{s///p;q}') 2662306a36Sopenharmony_ci 2762306a36Sopenharmony_ci$objdump -D --no-show-raw-insn --start-address="$kstart" --stop-address="$end_intr" "$vmlinux" | 2862306a36Sopenharmony_cised -E -n ' 2962306a36Sopenharmony_ci# match lines that start with a kernel address 3062306a36Sopenharmony_ci/^c[0-9a-f]*:\s*b/ { 3162306a36Sopenharmony_ci # drop branches via ctr or lr 3262306a36Sopenharmony_ci /\<b.?.?(ct|l)r/d 3362306a36Sopenharmony_ci # cope with some differences between Clang and GNU objdumps 3462306a36Sopenharmony_ci s/\<bt.?\s*[[:digit:]]+,/beq/ 3562306a36Sopenharmony_ci s/\<bf.?\s*[[:digit:]]+,/bne/ 3662306a36Sopenharmony_ci # tidy up 3762306a36Sopenharmony_ci s/\s0x/ / 3862306a36Sopenharmony_ci s/:// 3962306a36Sopenharmony_ci # format for the loop below 4062306a36Sopenharmony_ci s/^(\S+)\s+(\S+)\s+(\S+)\s*(\S*).*$/\1:\2:\3:\4/ 4162306a36Sopenharmony_ci # strip out condition registers 4262306a36Sopenharmony_ci s/:cr[0-7],/:/ 4362306a36Sopenharmony_ci p 4462306a36Sopenharmony_ci}' | { 4562306a36Sopenharmony_ci 4662306a36Sopenharmony_ciall_good=true 4762306a36Sopenharmony_ciwhile IFS=: read -r from branch to sym; do 4862306a36Sopenharmony_ci case "$to" in 4962306a36Sopenharmony_ci c*) to="0x$to" 5062306a36Sopenharmony_ci ;; 5162306a36Sopenharmony_ci .+*) 5262306a36Sopenharmony_ci to=${to#.+} 5362306a36Sopenharmony_ci if [ "$branch" = 'b' ]; then 5462306a36Sopenharmony_ci if (( to >= 0x2000000 )); then 5562306a36Sopenharmony_ci to=$(( to - 0x4000000 )) 5662306a36Sopenharmony_ci fi 5762306a36Sopenharmony_ci elif (( to >= 0x8000 )); then 5862306a36Sopenharmony_ci to=$(( to - 0x10000 )) 5962306a36Sopenharmony_ci fi 6062306a36Sopenharmony_ci printf -v to '0x%x' $(( "0x$from" + to )) 6162306a36Sopenharmony_ci ;; 6262306a36Sopenharmony_ci *) printf 'Unkown branch format\n' 6362306a36Sopenharmony_ci ;; 6462306a36Sopenharmony_ci esac 6562306a36Sopenharmony_ci if [ "$to" = "$sim" ]; then 6662306a36Sopenharmony_ci continue 6762306a36Sopenharmony_ci fi 6862306a36Sopenharmony_ci if (( to > end_intr )); then 6962306a36Sopenharmony_ci if $all_good; then 7062306a36Sopenharmony_ci printf '%s\n' 'WARNING: Unrelocated relative branches' 7162306a36Sopenharmony_ci all_good=false 7262306a36Sopenharmony_ci fi 7362306a36Sopenharmony_ci printf '%s %s-> %s %s\n' "$from" "$branch" "$to" "$sym" 7462306a36Sopenharmony_ci fi 7562306a36Sopenharmony_cidone 7662306a36Sopenharmony_ci 7762306a36Sopenharmony_ci$all_good 7862306a36Sopenharmony_ci 7962306a36Sopenharmony_ci} 80