xref: /rk3399_rockchip-uboot/scripts/stacktrace.sh (revision d0df954bf3d4978ee3feb94b80ec863063c704cc)
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
11SYMBOL_FILE=`find -name u-boot.sym`
12
13echo
14if [ $ARGS_N -eq 0 ]; then
15	echo "Usage: "
16	echo "	./scripts/stacktrace.sh <file>  // u-boot stacktrace info file"
17	exit 1
18elif [ ! -f $INPUT_FILE ]; then
19	echo "Can't find input file: $INPUT_FILE"
20	exit 1
21elif [ "$SYMBOL_FILE" = '' ] || [ ! -f $SYMBOL_FILE ]; then
22	echo "Can't find symbol file: u-boot.sym"
23	exit 1
24fi
25
26# Parse PC and LR
27echo "Call trace:"
28sed -n "/:   \[</p" $INPUT_FILE | while read line
29do
30	echo -n " ${line}  "
31
32	frame_pc_str=`echo $line | awk '{ print "0x"$3 }'`
33	frame_pc_dec=`echo $line | awk '{ print strtonum("0x"$3); }'`
34	frame_pc_hex=`echo "obase=16;${frame_pc_dec}"|bc |tr '[A-Z]' '[a-z]'`
35
36	f_pc_dec=`cat u-boot.sym | sort | awk '/\.text/ { if (strtonum("0x"$1) > '$frame_pc_str') { print fpc; exit; } fpc=strtonum("0x"$1); }'`
37	f_pc_hex=`echo "obase=16;${f_pc_dec}"|bc |tr '[A-Z]' '[a-z]'`
38	f_offset_dec=$((frame_pc_dec-f_pc_dec))
39	f_offset_hex=`echo "obase=16;${f_offset_dec}"|bc |tr '[A-Z]' '[a-z]'`
40
41	cat u-boot.sym | sort |
42	awk -v foffset=$f_offset_hex '/\.text/ {
43		if (strtonum("0x"$1) > '$frame_pc_str') {
44			printf("%s+0x%s/0x%x\n", fname, foffset, fsize);
45			exit
46		}
47		fname=$NF;
48		fsize=strtonum("0x"$5);
49		fpc=strtonum("0x"$1);
50	}'
51done
52echo
53
54# Parse stack
55echo "Stack:"
56sed -n "/        \[</p" $INPUT_FILE | while read line
57do
58	echo -n "       ${line}  "
59
60	frame_pc_str=`echo $line | awk '{ print "0x"$2 }'`
61	frame_pc_dec=`echo $line | awk '{ print strtonum("0x"$2); }'`
62	frame_pc_hex=`echo "obase=16;${frame_pc_dec}"|bc |tr '[A-Z]' '[a-z]'`
63
64	f_pc_dec=`cat u-boot.sym | sort | awk '/\.text/ { if (strtonum("0x"$1) > '$frame_pc_str') { print fpc; exit; } fpc=strtonum("0x"$1); }'`
65	f_pc_hex=`echo "obase=16;${f_pc_dec}"|bc |tr '[A-Z]' '[a-z]'`
66	f_offset_dec=$((frame_pc_dec-f_pc_dec))
67	f_offset_hex=`echo "obase=16;${f_offset_dec}"|bc |tr '[A-Z]' '[a-z]'`
68
69	cat u-boot.sym | sort |
70	awk -v foffset=$f_offset_hex '/\.text/ {
71		if (strtonum("0x"$1) > '$frame_pc_str') {
72			printf("%s+0x%s/0x%x\n", fname, foffset, fsize);
73			exit
74		}
75		fname=$NF;
76		fsize=strtonum("0x"$5);
77		fpc=strtonum("0x"$1);
78	}'
79done
80echo
81