xref: /OK3568_Linux_fs/u-boot/scripts/stacktrace.sh (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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
47echo "SYMBOL File: ${SYM_FILE}"
48echo
49# Parse PC and LR
50echo "Call trace:"
51grep '\[< ' ${INPUT_FILE} | grep '>\]' | grep [PC,LR] | while read line
52do
53	echo -n " ${line}  "
54
55	frame_pc_str=`echo ${line} | awk '{ print "0x"$3 }'`
56	frame_pc_dec=`echo ${line} | awk '{ print strtonum("0x"$3); }'`
57	frame_pc_hex=`echo "obase=16;${frame_pc_dec}"|bc |tr '[A-Z]' '[a-z]'`
58
59	f_pc_dec=`cat ${SYM_FILE} | sort | awk '/\.text/ { if (strtonum("0x"$1) > '${frame_pc_str}') { print fpc; exit; } fpc=strtonum("0x"$1); }'`
60	f_pc_hex=`echo "obase=16;${f_pc_dec}"|bc |tr '[A-Z]' '[a-z]'`
61	f_offset_dec=$((frame_pc_dec-f_pc_dec))
62	f_offset_hex=`echo "obase=16;${f_offset_dec}"|bc |tr '[A-Z]' '[a-z]'`
63
64	cat ${SYM_FILE} | sort |
65	awk -v foffset=${f_offset_hex} '/\.text/ {
66		if (strtonum("0x"$1) > '${frame_pc_str}') {
67			printf("%s+0x%s/0x%x      ", fname, foffset, fsize);
68			exit
69		}
70		fname=$NF;
71		fsize=strtonum("0x"$5);
72		fpc=strtonum("0x"$1);
73	}'
74
75	func_path=`./make.sh ${frame_pc_str} | awk '{ print $1 }' | sed -n "/home/p"`
76	func_path=`echo ${func_path##*boot/}`
77	echo ${func_path}
78done
79echo
80
81# Parse stack
82echo "Stack:"
83grep '\[< ' ${INPUT_FILE} | grep '>\]' | grep -v [PC,LR] | while read line
84do
85	echo -n "       ${line}  "
86
87	frame_pc_str=`echo ${line} | awk '{ print "0x"$2 }'`
88	frame_pc_dec=`echo ${line} | awk '{ print strtonum("0x"$2); }'`
89	frame_pc_hex=`echo "obase=16;${frame_pc_dec}"|bc |tr '[A-Z]' '[a-z]'`
90
91	f_pc_dec=`cat ${SYM_FILE} | sort | awk '/\.text/ { if (strtonum("0x"$1) > '${frame_pc_str}') { print fpc; exit; } fpc=strtonum("0x"$1); }'`
92	f_pc_hex=`echo "obase=16;${f_pc_dec}"|bc |tr '[A-Z]' '[a-z]'`
93	f_offset_dec=$((frame_pc_dec-f_pc_dec))
94	f_offset_hex=`echo "obase=16;${f_offset_dec}"|bc |tr '[A-Z]' '[a-z]'`
95
96	cat ${SYM_FILE} | sort |
97	awk -v foffset=${f_offset_hex} '/\.text/ {
98		if (strtonum("0x"$1) > '${frame_pc_str}') {
99			printf("%s+0x%s/0x%x\n", fname, foffset, fsize);
100			exit
101		}
102		fname=$NF;
103		fsize=strtonum("0x"$5);
104		fpc=strtonum("0x"$1);
105	}'
106done
107echo
108
109# PC instruction
110echo "PC Surrounding Instructions:"
111line=`grep '\[< ' ${INPUT_FILE} | grep '>\]' | grep [PC]`
112frame_pc_str=`echo ${line} | awk '{ print "0x"$3 }'`
113frame_pc_dec=`echo ${line} | awk '{ print strtonum("0x"$3); }'`
114# Handle Thumb instr
115if [ `expr ${frame_pc_dec} % 2` -ne 0 ];then
116	frame_pc_dec=`expr ${frame_pc_dec} - 1`
117fi
118frame_pc_hex=`echo "obase=16;${frame_pc_dec}"|bc |tr '[A-Z]' '[a-z]'`
119PC_INSTR=`./make.sh ${ELF_FILE} | grep -5 -m 1 "${frame_pc_hex}:"`
120echo "${PC_INSTR}"
121echo
122