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