1*4882a593Smuzhiyun#!/bin/bash 2*4882a593Smuzhiyun# 3*4882a593Smuzhiyun# Copyright (c) 2019 Fuzhou Rockchip Electronics Co., Ltd 4*4882a593Smuzhiyun# 5*4882a593Smuzhiyun# SPDX-License-Identifier: GPL-2.0 6*4882a593Smuzhiyun# 7*4882a593Smuzhiyun 8*4882a593Smuzhiyunset -e 9*4882a593Smuzhiyun 10*4882a593SmuzhiyunINPUT_FILE=$1 11*4882a593SmuzhiyunTPL_SPL=$2 12*4882a593Smuzhiyun 13*4882a593Smuzhiyunif [ "${TPL_SPL}" = "tpl" ]; then 14*4882a593Smuzhiyun SYM_FILE=`find -name u-boot-tpl.sym` 15*4882a593Smuzhiyun ELF_FILE="elf tpl" 16*4882a593Smuzhiyunelif [ "${TPL_SPL}" = "spl" ]; then 17*4882a593Smuzhiyun SYM_FILE=`find -name u-boot-spl.sym` 18*4882a593Smuzhiyun ELF_FILE="elf spl" 19*4882a593Smuzhiyunelse 20*4882a593Smuzhiyun SYM_FILE=`find -name u-boot.sym` 21*4882a593Smuzhiyun ELF_FILE="elf" 22*4882a593Smuzhiyunfi 23*4882a593Smuzhiyun 24*4882a593Smuzhiyunecho 25*4882a593Smuzhiyunif [ $# -eq 0 ]; then 26*4882a593Smuzhiyun echo "Usage: " 27*4882a593Smuzhiyun echo " ./scripts/stacktrace.sh <file> <type>" 28*4882a593Smuzhiyun echo 29*4882a593Smuzhiyun echo "Param:" 30*4882a593Smuzhiyun echo " <file>: stacktrace info file" 31*4882a593Smuzhiyun echo " <type>: none, spl, tpl" 32*4882a593Smuzhiyun echo 33*4882a593Smuzhiyun echo "Example:" 34*4882a593Smuzhiyun echo " ./scripts/stacktrace.sh ./dump.txt" 35*4882a593Smuzhiyun echo " ./scripts/stacktrace.sh ./dump.txt tpl" 36*4882a593Smuzhiyun echo " ./scripts/stacktrace.sh ./dump.txt spl" 37*4882a593Smuzhiyun echo 38*4882a593Smuzhiyun exit 1 39*4882a593Smuzhiyunelif [ ! -f ${INPUT_FILE} ]; then 40*4882a593Smuzhiyun echo "ERROR: No ${INPUT_FILE}" 41*4882a593Smuzhiyun exit 1 42*4882a593Smuzhiyunelif [ "${SYM_FILE}" = '' ] || [ ! -f ${SYM_FILE} ]; then 43*4882a593Smuzhiyun echo "ERROR: No ${SYM_FILE}" 44*4882a593Smuzhiyun exit 1 45*4882a593Smuzhiyunfi 46*4882a593Smuzhiyun 47*4882a593Smuzhiyunecho "SYMBOL File: ${SYM_FILE}" 48*4882a593Smuzhiyunecho 49*4882a593Smuzhiyun# Parse PC and LR 50*4882a593Smuzhiyunecho "Call trace:" 51*4882a593Smuzhiyungrep '\[< ' ${INPUT_FILE} | grep '>\]' | grep [PC,LR] | while read line 52*4882a593Smuzhiyundo 53*4882a593Smuzhiyun echo -n " ${line} " 54*4882a593Smuzhiyun 55*4882a593Smuzhiyun frame_pc_str=`echo ${line} | awk '{ print "0x"$3 }'` 56*4882a593Smuzhiyun frame_pc_dec=`echo ${line} | awk '{ print strtonum("0x"$3); }'` 57*4882a593Smuzhiyun frame_pc_hex=`echo "obase=16;${frame_pc_dec}"|bc |tr '[A-Z]' '[a-z]'` 58*4882a593Smuzhiyun 59*4882a593Smuzhiyun f_pc_dec=`cat ${SYM_FILE} | sort | awk '/\.text/ { if (strtonum("0x"$1) > '${frame_pc_str}') { print fpc; exit; } fpc=strtonum("0x"$1); }'` 60*4882a593Smuzhiyun f_pc_hex=`echo "obase=16;${f_pc_dec}"|bc |tr '[A-Z]' '[a-z]'` 61*4882a593Smuzhiyun f_offset_dec=$((frame_pc_dec-f_pc_dec)) 62*4882a593Smuzhiyun f_offset_hex=`echo "obase=16;${f_offset_dec}"|bc |tr '[A-Z]' '[a-z]'` 63*4882a593Smuzhiyun 64*4882a593Smuzhiyun cat ${SYM_FILE} | sort | 65*4882a593Smuzhiyun awk -v foffset=${f_offset_hex} '/\.text/ { 66*4882a593Smuzhiyun if (strtonum("0x"$1) > '${frame_pc_str}') { 67*4882a593Smuzhiyun printf("%s+0x%s/0x%x ", fname, foffset, fsize); 68*4882a593Smuzhiyun exit 69*4882a593Smuzhiyun } 70*4882a593Smuzhiyun fname=$NF; 71*4882a593Smuzhiyun fsize=strtonum("0x"$5); 72*4882a593Smuzhiyun fpc=strtonum("0x"$1); 73*4882a593Smuzhiyun }' 74*4882a593Smuzhiyun 75*4882a593Smuzhiyun func_path=`./make.sh ${frame_pc_str} | awk '{ print $1 }' | sed -n "/home/p"` 76*4882a593Smuzhiyun func_path=`echo ${func_path##*boot/}` 77*4882a593Smuzhiyun echo ${func_path} 78*4882a593Smuzhiyundone 79*4882a593Smuzhiyunecho 80*4882a593Smuzhiyun 81*4882a593Smuzhiyun# Parse stack 82*4882a593Smuzhiyunecho "Stack:" 83*4882a593Smuzhiyungrep '\[< ' ${INPUT_FILE} | grep '>\]' | grep -v [PC,LR] | while read line 84*4882a593Smuzhiyundo 85*4882a593Smuzhiyun echo -n " ${line} " 86*4882a593Smuzhiyun 87*4882a593Smuzhiyun frame_pc_str=`echo ${line} | awk '{ print "0x"$2 }'` 88*4882a593Smuzhiyun frame_pc_dec=`echo ${line} | awk '{ print strtonum("0x"$2); }'` 89*4882a593Smuzhiyun frame_pc_hex=`echo "obase=16;${frame_pc_dec}"|bc |tr '[A-Z]' '[a-z]'` 90*4882a593Smuzhiyun 91*4882a593Smuzhiyun f_pc_dec=`cat ${SYM_FILE} | sort | awk '/\.text/ { if (strtonum("0x"$1) > '${frame_pc_str}') { print fpc; exit; } fpc=strtonum("0x"$1); }'` 92*4882a593Smuzhiyun f_pc_hex=`echo "obase=16;${f_pc_dec}"|bc |tr '[A-Z]' '[a-z]'` 93*4882a593Smuzhiyun f_offset_dec=$((frame_pc_dec-f_pc_dec)) 94*4882a593Smuzhiyun f_offset_hex=`echo "obase=16;${f_offset_dec}"|bc |tr '[A-Z]' '[a-z]'` 95*4882a593Smuzhiyun 96*4882a593Smuzhiyun cat ${SYM_FILE} | sort | 97*4882a593Smuzhiyun awk -v foffset=${f_offset_hex} '/\.text/ { 98*4882a593Smuzhiyun if (strtonum("0x"$1) > '${frame_pc_str}') { 99*4882a593Smuzhiyun printf("%s+0x%s/0x%x\n", fname, foffset, fsize); 100*4882a593Smuzhiyun exit 101*4882a593Smuzhiyun } 102*4882a593Smuzhiyun fname=$NF; 103*4882a593Smuzhiyun fsize=strtonum("0x"$5); 104*4882a593Smuzhiyun fpc=strtonum("0x"$1); 105*4882a593Smuzhiyun }' 106*4882a593Smuzhiyundone 107*4882a593Smuzhiyunecho 108*4882a593Smuzhiyun 109*4882a593Smuzhiyun# PC instruction 110*4882a593Smuzhiyunecho "PC Surrounding Instructions:" 111*4882a593Smuzhiyunline=`grep '\[< ' ${INPUT_FILE} | grep '>\]' | grep [PC]` 112*4882a593Smuzhiyunframe_pc_str=`echo ${line} | awk '{ print "0x"$3 }'` 113*4882a593Smuzhiyunframe_pc_dec=`echo ${line} | awk '{ print strtonum("0x"$3); }'` 114*4882a593Smuzhiyun# Handle Thumb instr 115*4882a593Smuzhiyunif [ `expr ${frame_pc_dec} % 2` -ne 0 ];then 116*4882a593Smuzhiyun frame_pc_dec=`expr ${frame_pc_dec} - 1` 117*4882a593Smuzhiyunfi 118*4882a593Smuzhiyunframe_pc_hex=`echo "obase=16;${frame_pc_dec}"|bc |tr '[A-Z]' '[a-z]'` 119*4882a593SmuzhiyunPC_INSTR=`./make.sh ${ELF_FILE} | grep -5 -m 1 "${frame_pc_hex}:"` 120*4882a593Smuzhiyunecho "${PC_INSTR}" 121*4882a593Smuzhiyunecho 122