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