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