xref: /rk3399_rockchip-uboot/scripts/stacktrace.sh (revision f961f5ac078e5d451dddeab17a27896742fbb4da)
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