18c2ecf20Sopenharmony_ci#!/bin/bash 28c2ecf20Sopenharmony_ci# SPDX-License-Identifier: GPL-2.0+ 38c2ecf20Sopenharmony_ci# Copyright © 2016,2020 IBM Corporation 48c2ecf20Sopenharmony_ci# 58c2ecf20Sopenharmony_ci# This script checks the unrelocated code of a vmlinux for "suspicious" 68c2ecf20Sopenharmony_ci# branches to relocated code (head_64.S code). 78c2ecf20Sopenharmony_ci 88c2ecf20Sopenharmony_ci# Have Kbuild supply the path to objdump and nm so we handle cross compilation. 98c2ecf20Sopenharmony_ciobjdump="$1" 108c2ecf20Sopenharmony_cinm="$2" 118c2ecf20Sopenharmony_civmlinux="$3" 128c2ecf20Sopenharmony_ci 138c2ecf20Sopenharmony_cikstart=0xc000000000000000 148c2ecf20Sopenharmony_ci 158c2ecf20Sopenharmony_ciend_intr=0x$($nm -p "$vmlinux" | 168c2ecf20Sopenharmony_ci sed -E -n '/\s+[[:alpha:]]\s+__end_interrupts\s*$/{s///p;q}') 178c2ecf20Sopenharmony_ciif [ "$end_intr" = "0x" ]; then 188c2ecf20Sopenharmony_ci exit 0 198c2ecf20Sopenharmony_cifi 208c2ecf20Sopenharmony_ci 218c2ecf20Sopenharmony_ci# we know that there is a correct branch to 228c2ecf20Sopenharmony_ci# __start_initialization_multiplatform, so find its address 238c2ecf20Sopenharmony_ci# so we can exclude it. 248c2ecf20Sopenharmony_cisim=0x$($nm -p "$vmlinux" | 258c2ecf20Sopenharmony_ci sed -E -n '/\s+[[:alpha:]]\s+__start_initialization_multiplatform\s*$/{s///p;q}') 268c2ecf20Sopenharmony_ci 278c2ecf20Sopenharmony_ci$objdump -D --no-show-raw-insn --start-address="$kstart" --stop-address="$end_intr" "$vmlinux" | 288c2ecf20Sopenharmony_cised -E -n ' 298c2ecf20Sopenharmony_ci# match lines that start with a kernel address 308c2ecf20Sopenharmony_ci/^c[0-9a-f]*:\s*b/ { 318c2ecf20Sopenharmony_ci # drop branches via ctr or lr 328c2ecf20Sopenharmony_ci /\<b.?.?(ct|l)r/d 338c2ecf20Sopenharmony_ci # cope with some differences between Clang and GNU objdumps 348c2ecf20Sopenharmony_ci s/\<bt.?\s*[[:digit:]]+,/beq/ 358c2ecf20Sopenharmony_ci s/\<bf.?\s*[[:digit:]]+,/bne/ 368c2ecf20Sopenharmony_ci # tidy up 378c2ecf20Sopenharmony_ci s/\s0x/ / 388c2ecf20Sopenharmony_ci s/:// 398c2ecf20Sopenharmony_ci # format for the loop below 408c2ecf20Sopenharmony_ci s/^(\S+)\s+(\S+)\s+(\S+)\s*(\S*).*$/\1:\2:\3:\4/ 418c2ecf20Sopenharmony_ci # strip out condition registers 428c2ecf20Sopenharmony_ci s/:cr[0-7],/:/ 438c2ecf20Sopenharmony_ci p 448c2ecf20Sopenharmony_ci}' | { 458c2ecf20Sopenharmony_ci 468c2ecf20Sopenharmony_ciall_good=true 478c2ecf20Sopenharmony_ciwhile IFS=: read -r from branch to sym; do 488c2ecf20Sopenharmony_ci case "$to" in 498c2ecf20Sopenharmony_ci c*) to="0x$to" 508c2ecf20Sopenharmony_ci ;; 518c2ecf20Sopenharmony_ci .+*) 528c2ecf20Sopenharmony_ci to=${to#.+} 538c2ecf20Sopenharmony_ci if [ "$branch" = 'b' ]; then 548c2ecf20Sopenharmony_ci if (( to >= 0x2000000 )); then 558c2ecf20Sopenharmony_ci to=$(( to - 0x4000000 )) 568c2ecf20Sopenharmony_ci fi 578c2ecf20Sopenharmony_ci elif (( to >= 0x8000 )); then 588c2ecf20Sopenharmony_ci to=$(( to - 0x10000 )) 598c2ecf20Sopenharmony_ci fi 608c2ecf20Sopenharmony_ci printf -v to '0x%x' $(( "0x$from" + to )) 618c2ecf20Sopenharmony_ci ;; 628c2ecf20Sopenharmony_ci *) printf 'Unkown branch format\n' 638c2ecf20Sopenharmony_ci ;; 648c2ecf20Sopenharmony_ci esac 658c2ecf20Sopenharmony_ci if [ "$to" = "$sim" ]; then 668c2ecf20Sopenharmony_ci continue 678c2ecf20Sopenharmony_ci fi 688c2ecf20Sopenharmony_ci if (( to > end_intr )); then 698c2ecf20Sopenharmony_ci if $all_good; then 708c2ecf20Sopenharmony_ci printf '%s\n' 'WARNING: Unrelocated relative branches' 718c2ecf20Sopenharmony_ci all_good=false 728c2ecf20Sopenharmony_ci fi 738c2ecf20Sopenharmony_ci printf '%s %s-> %s %s\n' "$from" "$branch" "$to" "$sym" 748c2ecf20Sopenharmony_ci fi 758c2ecf20Sopenharmony_cidone 768c2ecf20Sopenharmony_ci 778c2ecf20Sopenharmony_ci$all_good 788c2ecf20Sopenharmony_ci 798c2ecf20Sopenharmony_ci} 80