xref: /rk3399_rockchip-uboot/scripts/stacktrace.sh (revision f961f5ac078e5d451dddeab17a27896742fbb4da)
1b97fba2cSJoseph Chen#!/bin/bash
2b97fba2cSJoseph Chen#
3b97fba2cSJoseph Chen# Copyright (c) 2019 Fuzhou Rockchip Electronics Co., Ltd
4b97fba2cSJoseph Chen#
5b97fba2cSJoseph Chen# SPDX-License-Identifier: GPL-2.0
6b97fba2cSJoseph Chen#
7b97fba2cSJoseph Chen
8b97fba2cSJoseph Chenset -e
9b97fba2cSJoseph ChenARGS_N=$#
10b97fba2cSJoseph ChenINPUT_FILE=$1
1173251fc2SJoseph ChenTPL_SPL=$2
1273251fc2SJoseph Chen
1373251fc2SJoseph Chen
1473251fc2SJoseph Chenif [ "$TPL_SPL" = "tpl" ]; then
1573251fc2SJoseph Chen	SYMBOL_FILE=`find -name u-boot-tpl.sym`
16*f961f5acSJoseph Chen	ELF_FILE="elf tpl"
1773251fc2SJoseph Chenelif [ "$TPL_SPL" = "spl" ]; then
1873251fc2SJoseph Chen	SYMBOL_FILE=`find -name u-boot-spl.sym`
19*f961f5acSJoseph Chen	ELF_FILE="elf spl"
2073251fc2SJoseph Chenelse
21b97fba2cSJoseph Chen	SYMBOL_FILE=`find -name u-boot.sym`
22*f961f5acSJoseph Chen	ELF_FILE="elf"
2373251fc2SJoseph Chenfi
24b97fba2cSJoseph Chen
25b97fba2cSJoseph Chenecho
26b97fba2cSJoseph Chenif [ $ARGS_N -eq 0 ]; then
27b97fba2cSJoseph Chen	echo "Usage: "
2873251fc2SJoseph Chen	echo "	./scripts/stacktrace.sh <file> <type>"
2973251fc2SJoseph Chen	echo
3073251fc2SJoseph Chen	echo "Param:"
3173251fc2SJoseph Chen	echo "	<file>: stacktrace info file"
3273251fc2SJoseph Chen	echo "	<type>: none, spl, tpl"
3373251fc2SJoseph Chen	echo
3473251fc2SJoseph Chen	echo "Example:"
3573251fc2SJoseph Chen	echo "	./scripts/stacktrace.sh ./dump.txt"
3673251fc2SJoseph Chen	echo "	./scripts/stacktrace.sh ./dump.txt tpl"
3773251fc2SJoseph Chen	echo "	./scripts/stacktrace.sh ./dump.txt spl"
3873251fc2SJoseph Chen	echo
39b97fba2cSJoseph Chen	exit 1
40b97fba2cSJoseph Chenelif [ ! -f $INPUT_FILE ]; then
41b97fba2cSJoseph Chen	echo "Can't find input file: $INPUT_FILE"
42b97fba2cSJoseph Chen	exit 1
43b97fba2cSJoseph Chenelif [ "$SYMBOL_FILE" = '' ] || [ ! -f $SYMBOL_FILE ]; then
4473251fc2SJoseph Chen	echo "Can't find symbol file: ${SYMBOL_FILE}"
45b97fba2cSJoseph Chen	exit 1
46b97fba2cSJoseph Chenfi
47b97fba2cSJoseph Chen
4873251fc2SJoseph Chenecho "SYMBOL File: ${SYMBOL_FILE}"
4973251fc2SJoseph Chenecho
50b97fba2cSJoseph Chen# Parse PC and LR
51b97fba2cSJoseph Chenecho "Call trace:"
52763ecaa3SJoseph Chengrep '\[< ' $INPUT_FILE | grep '>\]' | grep [PC,LR] | while read line
53b97fba2cSJoseph Chendo
54b97fba2cSJoseph Chen	echo -n " ${line}  "
55b97fba2cSJoseph Chen
56b97fba2cSJoseph Chen	frame_pc_str=`echo $line | awk '{ print "0x"$3 }'`
57b97fba2cSJoseph Chen	frame_pc_dec=`echo $line | awk '{ print strtonum("0x"$3); }'`
58b97fba2cSJoseph Chen	frame_pc_hex=`echo "obase=16;${frame_pc_dec}"|bc |tr '[A-Z]' '[a-z]'`
59b97fba2cSJoseph Chen
6073251fc2SJoseph Chen	f_pc_dec=`cat ${SYMBOL_FILE} | sort | awk '/\.text/ { if (strtonum("0x"$1) > '$frame_pc_str') { print fpc; exit; } fpc=strtonum("0x"$1); }'`
61b97fba2cSJoseph Chen	f_pc_hex=`echo "obase=16;${f_pc_dec}"|bc |tr '[A-Z]' '[a-z]'`
62b97fba2cSJoseph Chen	f_offset_dec=$((frame_pc_dec-f_pc_dec))
63b97fba2cSJoseph Chen	f_offset_hex=`echo "obase=16;${f_offset_dec}"|bc |tr '[A-Z]' '[a-z]'`
64b97fba2cSJoseph Chen
6573251fc2SJoseph Chen	cat ${SYMBOL_FILE} | sort |
66b97fba2cSJoseph Chen	awk -v foffset=$f_offset_hex '/\.text/ {
67b97fba2cSJoseph Chen		if (strtonum("0x"$1) > '$frame_pc_str') {
6853307949SJoseph Chen			printf("%s+0x%s/0x%x      ", fname, foffset, fsize);
69b97fba2cSJoseph Chen			exit
70b97fba2cSJoseph Chen		}
71b97fba2cSJoseph Chen		fname=$NF;
72b97fba2cSJoseph Chen		fsize=strtonum("0x"$5);
73b97fba2cSJoseph Chen		fpc=strtonum("0x"$1);
74b97fba2cSJoseph Chen	}'
7553307949SJoseph Chen
7653307949SJoseph Chen	func_path=`./make.sh $frame_pc_str | awk '{ print $1 }' | sed -n "/home/p"`
7753307949SJoseph Chen	func_path=`echo ${func_path##*boot/}`
7853307949SJoseph Chen	echo $func_path
79b97fba2cSJoseph Chendone
80b97fba2cSJoseph Chenecho
81b97fba2cSJoseph Chen
82b97fba2cSJoseph Chen# Parse stack
83b97fba2cSJoseph Chenecho "Stack:"
84763ecaa3SJoseph Chengrep '\[< ' $INPUT_FILE | grep '>\]' | grep -v [PC,LR] | while read line
85b97fba2cSJoseph Chendo
86b97fba2cSJoseph Chen	echo -n "       ${line}  "
87b97fba2cSJoseph Chen
88b97fba2cSJoseph Chen	frame_pc_str=`echo $line | awk '{ print "0x"$2 }'`
89b97fba2cSJoseph Chen	frame_pc_dec=`echo $line | awk '{ print strtonum("0x"$2); }'`
90b97fba2cSJoseph Chen	frame_pc_hex=`echo "obase=16;${frame_pc_dec}"|bc |tr '[A-Z]' '[a-z]'`
91b97fba2cSJoseph Chen
9273251fc2SJoseph Chen	f_pc_dec=`cat ${SYMBOL_FILE} | sort | awk '/\.text/ { if (strtonum("0x"$1) > '$frame_pc_str') { print fpc; exit; } fpc=strtonum("0x"$1); }'`
93b97fba2cSJoseph Chen	f_pc_hex=`echo "obase=16;${f_pc_dec}"|bc |tr '[A-Z]' '[a-z]'`
94b97fba2cSJoseph Chen	f_offset_dec=$((frame_pc_dec-f_pc_dec))
95b97fba2cSJoseph Chen	f_offset_hex=`echo "obase=16;${f_offset_dec}"|bc |tr '[A-Z]' '[a-z]'`
96b97fba2cSJoseph Chen
9773251fc2SJoseph Chen	cat ${SYMBOL_FILE} | sort |
98b97fba2cSJoseph Chen	awk -v foffset=$f_offset_hex '/\.text/ {
99b97fba2cSJoseph Chen		if (strtonum("0x"$1) > '$frame_pc_str') {
100b97fba2cSJoseph Chen			printf("%s+0x%s/0x%x\n", fname, foffset, fsize);
101b97fba2cSJoseph Chen			exit
102b97fba2cSJoseph Chen		}
103b97fba2cSJoseph Chen		fname=$NF;
104b97fba2cSJoseph Chen		fsize=strtonum("0x"$5);
105b97fba2cSJoseph Chen		fpc=strtonum("0x"$1);
106b97fba2cSJoseph Chen	}'
107b97fba2cSJoseph Chendone
108b97fba2cSJoseph Chenecho
109*f961f5acSJoseph Chen
110*f961f5acSJoseph Chen# PC instruction
111*f961f5acSJoseph Chenecho " PC Surrounding Instructions:"
112*f961f5acSJoseph Chenline=`grep '\[< ' $INPUT_FILE | grep '>\]' | grep [PC]`
113*f961f5acSJoseph Chenframe_pc_str=`echo $line | awk '{ print "0x"$3 }'`
114*f961f5acSJoseph Chenframe_pc_dec=`echo $line | awk '{ print strtonum("0x"$3); }'`
115*f961f5acSJoseph Chenframe_pc_hex=`echo "obase=16;${frame_pc_dec}"|bc |tr '[A-Z]' '[a-z]'`
116*f961f5acSJoseph ChenPC_INSTR=`./make.sh ${ELF_FILE} | grep -5 -m 1 "${frame_pc_hex}:"`
117*f961f5acSJoseph Chenecho "${PC_INSTR}"
118*f961f5acSJoseph Chenecho
119