18c2ecf20Sopenharmony_ci# Copyright © 2016 IBM Corporation 28c2ecf20Sopenharmony_ci 38c2ecf20Sopenharmony_ci# This program is free software; you can redistribute it and/or 48c2ecf20Sopenharmony_ci# modify it under the terms of the GNU General Public License 58c2ecf20Sopenharmony_ci# as published by the Free Software Foundation; either version 68c2ecf20Sopenharmony_ci# 2 of the License, or (at your option) any later version. 78c2ecf20Sopenharmony_ci 88c2ecf20Sopenharmony_ci# This script checks the head of a vmlinux for linker stubs that 98c2ecf20Sopenharmony_ci# break our placement of fixed-location code for 64-bit. 108c2ecf20Sopenharmony_ci 118c2ecf20Sopenharmony_ci# based on relocs_check.pl 128c2ecf20Sopenharmony_ci# Copyright © 2009 IBM Corporation 138c2ecf20Sopenharmony_ci 148c2ecf20Sopenharmony_ci# NOTE! 158c2ecf20Sopenharmony_ci# 168c2ecf20Sopenharmony_ci# If the build dies here, it's likely code in head_64.S/exception-64*.S or 178c2ecf20Sopenharmony_ci# nearby, is branching to labels it can't reach directly, which results in the 188c2ecf20Sopenharmony_ci# linker inserting branch stubs. This can move code around in ways that break 198c2ecf20Sopenharmony_ci# the fixed section calculations (head-64.h). To debug this, disassemble the 208c2ecf20Sopenharmony_ci# vmlinux and look for branch stubs (long_branch, plt_branch, etc.) in the 218c2ecf20Sopenharmony_ci# fixed section region (0 - 0x8000ish). Check what code is calling those stubs, 228c2ecf20Sopenharmony_ci# and perhaps change so a direct branch can reach. 238c2ecf20Sopenharmony_ci# 248c2ecf20Sopenharmony_ci# A ".linker_stub_catch" section is used to catch some stubs generated by 258c2ecf20Sopenharmony_ci# early .text code, which tend to get placed at the start of the section. 268c2ecf20Sopenharmony_ci# If there are too many such stubs, they can overflow this section. Expanding 278c2ecf20Sopenharmony_ci# it may help (or reducing the number of stub branches). 288c2ecf20Sopenharmony_ci# 298c2ecf20Sopenharmony_ci# Linker stubs use the TOC pointer, so even if fixed section code could 308c2ecf20Sopenharmony_ci# tolerate them being inserted into head code, they can't be allowed in low 318c2ecf20Sopenharmony_ci# level entry code (boot, interrupt vectors, etc) until r2 is set up. This 328c2ecf20Sopenharmony_ci# could cause the kernel to die in early boot. 338c2ecf20Sopenharmony_ci 348c2ecf20Sopenharmony_ci# Allow for verbose output 358c2ecf20Sopenharmony_ciif [ "$V" = "1" ]; then 368c2ecf20Sopenharmony_ci set -x 378c2ecf20Sopenharmony_cifi 388c2ecf20Sopenharmony_ci 398c2ecf20Sopenharmony_ciif [ $# -lt 2 ]; then 408c2ecf20Sopenharmony_ci echo "$0 [path to nm] [path to vmlinux]" 1>&2 418c2ecf20Sopenharmony_ci exit 1 428c2ecf20Sopenharmony_cifi 438c2ecf20Sopenharmony_ci 448c2ecf20Sopenharmony_ci# Have Kbuild supply the path to nm so we handle cross compilation. 458c2ecf20Sopenharmony_cinm="$1" 468c2ecf20Sopenharmony_civmlinux="$2" 478c2ecf20Sopenharmony_ci 488c2ecf20Sopenharmony_ci# gcc-4.6-era toolchain make _stext an A (absolute) symbol rather than T 498c2ecf20Sopenharmony_ci$nm "$vmlinux" | grep -e " [TA] _stext$" -e " t start_first_256B$" -e " a text_start$" -e " t start_text$" > .tmp_symbols.txt 508c2ecf20Sopenharmony_ci 518c2ecf20Sopenharmony_ci 528c2ecf20Sopenharmony_civma=$(cat .tmp_symbols.txt | grep -e " [TA] _stext$" | cut -d' ' -f1) 538c2ecf20Sopenharmony_ci 548c2ecf20Sopenharmony_ciexpected_start_head_addr=$vma 558c2ecf20Sopenharmony_ci 568c2ecf20Sopenharmony_cistart_head_addr=$(cat .tmp_symbols.txt | grep " t start_first_256B$" | cut -d' ' -f1) 578c2ecf20Sopenharmony_ci 588c2ecf20Sopenharmony_ciif [ "$start_head_addr" != "$expected_start_head_addr" ]; then 598c2ecf20Sopenharmony_ci echo "ERROR: head code starts at $start_head_addr, should be $expected_start_head_addr" 608c2ecf20Sopenharmony_ci echo "ERROR: try to enable LD_HEAD_STUB_CATCH config option" 618c2ecf20Sopenharmony_ci echo "ERROR: see comments in arch/powerpc/tools/head_check.sh" 628c2ecf20Sopenharmony_ci 638c2ecf20Sopenharmony_ci exit 1 648c2ecf20Sopenharmony_cifi 658c2ecf20Sopenharmony_ci 668c2ecf20Sopenharmony_citop_vma=$(echo $vma | cut -d'0' -f1) 678c2ecf20Sopenharmony_ci 688c2ecf20Sopenharmony_ciexpected_start_text_addr=$(cat .tmp_symbols.txt | grep " a text_start$" | cut -d' ' -f1 | sed "s/^0/$top_vma/") 698c2ecf20Sopenharmony_ci 708c2ecf20Sopenharmony_cistart_text_addr=$(cat .tmp_symbols.txt | grep " t start_text$" | cut -d' ' -f1) 718c2ecf20Sopenharmony_ci 728c2ecf20Sopenharmony_ciif [ "$start_text_addr" != "$expected_start_text_addr" ]; then 738c2ecf20Sopenharmony_ci echo "ERROR: start_text address is $start_text_addr, should be $expected_start_text_addr" 748c2ecf20Sopenharmony_ci echo "ERROR: try to enable LD_HEAD_STUB_CATCH config option" 758c2ecf20Sopenharmony_ci echo "ERROR: see comments in arch/powerpc/tools/head_check.sh" 768c2ecf20Sopenharmony_ci 778c2ecf20Sopenharmony_ci exit 1 788c2ecf20Sopenharmony_cifi 798c2ecf20Sopenharmony_ci 808c2ecf20Sopenharmony_cirm -f .tmp_symbols.txt 81