xref: /rk3399_rockchip-uboot/scripts/stacktrace.sh (revision 91cbfde1a2679846bd858761e06bcb81397abc19)
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      ", fname, foffset, fsize);
45			exit
46		}
47		fname=$NF;
48		fsize=strtonum("0x"$5);
49		fpc=strtonum("0x"$1);
50	}'
51
52	func_path=`./make.sh $frame_pc_str | awk '{ print $1 }' | sed -n "/home/p"`
53	func_path=`echo ${func_path##*boot/}`
54	echo $func_path
55done
56echo
57
58# Parse stack
59echo "Stack:"
60sed -n "/        \[</p" $INPUT_FILE | while read line
61do
62	echo -n "       ${line}  "
63
64	frame_pc_str=`echo $line | awk '{ print "0x"$2 }'`
65	frame_pc_dec=`echo $line | awk '{ print strtonum("0x"$2); }'`
66	frame_pc_hex=`echo "obase=16;${frame_pc_dec}"|bc |tr '[A-Z]' '[a-z]'`
67
68	f_pc_dec=`cat u-boot.sym | sort | awk '/\.text/ { if (strtonum("0x"$1) > '$frame_pc_str') { print fpc; exit; } fpc=strtonum("0x"$1); }'`
69	f_pc_hex=`echo "obase=16;${f_pc_dec}"|bc |tr '[A-Z]' '[a-z]'`
70	f_offset_dec=$((frame_pc_dec-f_pc_dec))
71	f_offset_hex=`echo "obase=16;${f_offset_dec}"|bc |tr '[A-Z]' '[a-z]'`
72
73	cat u-boot.sym | sort |
74	awk -v foffset=$f_offset_hex '/\.text/ {
75		if (strtonum("0x"$1) > '$frame_pc_str') {
76			printf("%s+0x%s/0x%x\n", fname, foffset, fsize);
77			exit
78		}
79		fname=$NF;
80		fsize=strtonum("0x"$5);
81		fpc=strtonum("0x"$1);
82	}'
83done
84echo
85