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