xref: /rk3399_rockchip-uboot/scripts/stacktrace.sh (revision 79fbddf2fd547a73a92ba3a3868be3e30466a4d5)
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
97545a1ecSJoseph Chen
10b97fba2cSJoseph ChenINPUT_FILE=$1
1173251fc2SJoseph ChenTPL_SPL=$2
1273251fc2SJoseph Chen
137545a1ecSJoseph Chenif [ "${TPL_SPL}" = "tpl" ]; then
147545a1ecSJoseph Chen	SYM_FILE=`find -name u-boot-tpl.sym`
15f961f5acSJoseph Chen	ELF_FILE="elf tpl"
167545a1ecSJoseph Chenelif [ "${TPL_SPL}" = "spl" ]; then
177545a1ecSJoseph Chen	SYM_FILE=`find -name u-boot-spl.sym`
18f961f5acSJoseph Chen	ELF_FILE="elf spl"
1973251fc2SJoseph Chenelse
207545a1ecSJoseph Chen	SYM_FILE=`find -name u-boot.sym`
21f961f5acSJoseph Chen	ELF_FILE="elf"
2273251fc2SJoseph Chenfi
23b97fba2cSJoseph Chen
24b97fba2cSJoseph Chenecho
257545a1ecSJoseph Chenif [ $# -eq 0 ]; then
26b97fba2cSJoseph Chen	echo "Usage: "
2773251fc2SJoseph Chen	echo "	./scripts/stacktrace.sh <file> <type>"
2873251fc2SJoseph Chen	echo
2973251fc2SJoseph Chen	echo "Param:"
3073251fc2SJoseph Chen	echo "	<file>: stacktrace info file"
3173251fc2SJoseph Chen	echo "	<type>: none, spl, tpl"
3273251fc2SJoseph Chen	echo
3373251fc2SJoseph Chen	echo "Example:"
3473251fc2SJoseph Chen	echo "	./scripts/stacktrace.sh ./dump.txt"
3573251fc2SJoseph Chen	echo "	./scripts/stacktrace.sh ./dump.txt tpl"
3673251fc2SJoseph Chen	echo "	./scripts/stacktrace.sh ./dump.txt spl"
3773251fc2SJoseph Chen	echo
38b97fba2cSJoseph Chen	exit 1
397545a1ecSJoseph Chenelif [ ! -f ${INPUT_FILE} ]; then
407545a1ecSJoseph Chen	echo "ERROR: No ${INPUT_FILE}"
41b97fba2cSJoseph Chen	exit 1
427545a1ecSJoseph Chenelif [ "${SYM_FILE}" = '' ] || [ ! -f ${SYM_FILE} ]; then
437545a1ecSJoseph Chen	echo "ERROR: No ${SYM_FILE}"
44b97fba2cSJoseph Chen	exit 1
45b97fba2cSJoseph Chenfi
46b97fba2cSJoseph Chen
47*79fbddf2SJoseph Chendos2unix ${INPUT_FILE}
48*79fbddf2SJoseph Chen
49*79fbddf2SJoseph Chenecho
507545a1ecSJoseph Chenecho "SYMBOL File: ${SYM_FILE}"
5173251fc2SJoseph Chenecho
52b97fba2cSJoseph Chen# Parse PC and LR
53b97fba2cSJoseph Chenecho "Call trace:"
547545a1ecSJoseph Chengrep '\[< ' ${INPUT_FILE} | grep '>\]' | grep [PC,LR] | while read line
55b97fba2cSJoseph Chendo
56b97fba2cSJoseph Chen	echo -n " ${line}  "
57b97fba2cSJoseph Chen
587545a1ecSJoseph Chen	frame_pc_str=`echo ${line} | awk '{ print "0x"$3 }'`
597545a1ecSJoseph Chen	frame_pc_dec=`echo ${line} | awk '{ print strtonum("0x"$3); }'`
60b97fba2cSJoseph Chen	frame_pc_hex=`echo "obase=16;${frame_pc_dec}"|bc |tr '[A-Z]' '[a-z]'`
61b97fba2cSJoseph Chen
627545a1ecSJoseph Chen	f_pc_dec=`cat ${SYM_FILE} | sort | awk '/\.text/ { if (strtonum("0x"$1) > '${frame_pc_str}') { print fpc; exit; } fpc=strtonum("0x"$1); }'`
63b97fba2cSJoseph Chen	f_pc_hex=`echo "obase=16;${f_pc_dec}"|bc |tr '[A-Z]' '[a-z]'`
64b97fba2cSJoseph Chen	f_offset_dec=$((frame_pc_dec-f_pc_dec))
65b97fba2cSJoseph Chen	f_offset_hex=`echo "obase=16;${f_offset_dec}"|bc |tr '[A-Z]' '[a-z]'`
66b97fba2cSJoseph Chen
677545a1ecSJoseph Chen	cat ${SYM_FILE} | sort |
687545a1ecSJoseph Chen	awk -v foffset=${f_offset_hex} '/\.text/ {
697545a1ecSJoseph Chen		if (strtonum("0x"$1) > '${frame_pc_str}') {
7053307949SJoseph Chen			printf("%s+0x%s/0x%x      ", fname, foffset, fsize);
71b97fba2cSJoseph Chen			exit
72b97fba2cSJoseph Chen		}
73b97fba2cSJoseph Chen		fname=$NF;
74b97fba2cSJoseph Chen		fsize=strtonum("0x"$5);
75b97fba2cSJoseph Chen		fpc=strtonum("0x"$1);
76b97fba2cSJoseph Chen	}'
7753307949SJoseph Chen
787545a1ecSJoseph Chen	func_path=`./make.sh ${frame_pc_str} | awk '{ print $1 }' | sed -n "/home/p"`
7953307949SJoseph Chen	func_path=`echo ${func_path##*boot/}`
807545a1ecSJoseph Chen	echo ${func_path}
81b97fba2cSJoseph Chendone
82b97fba2cSJoseph Chenecho
83b97fba2cSJoseph Chen
84b97fba2cSJoseph Chen# Parse stack
85b97fba2cSJoseph Chenecho "Stack:"
867545a1ecSJoseph Chengrep '\[< ' ${INPUT_FILE} | grep '>\]' | grep -v [PC,LR] | while read line
87b97fba2cSJoseph Chendo
88b97fba2cSJoseph Chen	echo -n "       ${line}  "
89b97fba2cSJoseph Chen
907545a1ecSJoseph Chen	frame_pc_str=`echo ${line} | awk '{ print "0x"$2 }'`
917545a1ecSJoseph Chen	frame_pc_dec=`echo ${line} | awk '{ print strtonum("0x"$2); }'`
92b97fba2cSJoseph Chen	frame_pc_hex=`echo "obase=16;${frame_pc_dec}"|bc |tr '[A-Z]' '[a-z]'`
93b97fba2cSJoseph Chen
947545a1ecSJoseph Chen	f_pc_dec=`cat ${SYM_FILE} | sort | awk '/\.text/ { if (strtonum("0x"$1) > '${frame_pc_str}') { print fpc; exit; } fpc=strtonum("0x"$1); }'`
95b97fba2cSJoseph Chen	f_pc_hex=`echo "obase=16;${f_pc_dec}"|bc |tr '[A-Z]' '[a-z]'`
96b97fba2cSJoseph Chen	f_offset_dec=$((frame_pc_dec-f_pc_dec))
97b97fba2cSJoseph Chen	f_offset_hex=`echo "obase=16;${f_offset_dec}"|bc |tr '[A-Z]' '[a-z]'`
98b97fba2cSJoseph Chen
997545a1ecSJoseph Chen	cat ${SYM_FILE} | sort |
1007545a1ecSJoseph Chen	awk -v foffset=${f_offset_hex} '/\.text/ {
1017545a1ecSJoseph Chen		if (strtonum("0x"$1) > '${frame_pc_str}') {
102b97fba2cSJoseph Chen			printf("%s+0x%s/0x%x\n", fname, foffset, fsize);
103b97fba2cSJoseph Chen			exit
104b97fba2cSJoseph Chen		}
105b97fba2cSJoseph Chen		fname=$NF;
106b97fba2cSJoseph Chen		fsize=strtonum("0x"$5);
107b97fba2cSJoseph Chen		fpc=strtonum("0x"$1);
108b97fba2cSJoseph Chen	}'
109b97fba2cSJoseph Chendone
110b97fba2cSJoseph Chenecho
111f961f5acSJoseph Chen
112f961f5acSJoseph Chen# PC instruction
113f961f5acSJoseph Chenecho "PC Surrounding Instructions:"
1147545a1ecSJoseph Chenline=`grep '\[< ' ${INPUT_FILE} | grep '>\]' | grep [PC]`
1157545a1ecSJoseph Chenframe_pc_str=`echo ${line} | awk '{ print "0x"$3 }'`
1167545a1ecSJoseph Chenframe_pc_dec=`echo ${line} | awk '{ print strtonum("0x"$3); }'`
117050aa3bcSJoseph Chen# Handle Thumb instr
118050aa3bcSJoseph Chenif [ `expr ${frame_pc_dec} % 2` -ne 0 ];then
119050aa3bcSJoseph Chen	frame_pc_dec=`expr ${frame_pc_dec} - 1`
120050aa3bcSJoseph Chenfi
121f961f5acSJoseph Chenframe_pc_hex=`echo "obase=16;${frame_pc_dec}"|bc |tr '[A-Z]' '[a-z]'`
122f961f5acSJoseph ChenPC_INSTR=`./make.sh ${ELF_FILE} | grep -5 -m 1 "${frame_pc_hex}:"`
123f961f5acSJoseph Chenecho "${PC_INSTR}"
124f961f5acSJoseph Chenecho
125