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