xref: /openbmc/u-boot/scripts/decodecode (revision 3eceff64)
1*02c3a3d0SHeinrich Schuchardt#!/bin/sh
2*02c3a3d0SHeinrich Schuchardt# SPDX-License-Identifier: GPL-2.0
3*02c3a3d0SHeinrich Schuchardt# Disassemble the Code: line in Linux oopses
4*02c3a3d0SHeinrich Schuchardt# usage: decodecode < oops.file
5*02c3a3d0SHeinrich Schuchardt#
6*02c3a3d0SHeinrich Schuchardt# options: set env. variable AFLAGS=options to pass options to "as";
7*02c3a3d0SHeinrich Schuchardt# e.g., to decode an i386 oops on an x86_64 system, use:
8*02c3a3d0SHeinrich Schuchardt# AFLAGS=--32 decodecode < 386.oops
9*02c3a3d0SHeinrich Schuchardt
10*02c3a3d0SHeinrich Schuchardtcleanup() {
11*02c3a3d0SHeinrich Schuchardt	rm -f $T $T.s $T.o $T.oo $T.aa $T.dis
12*02c3a3d0SHeinrich Schuchardt	exit 1
13*02c3a3d0SHeinrich Schuchardt}
14*02c3a3d0SHeinrich Schuchardt
15*02c3a3d0SHeinrich Schuchardtdie() {
16*02c3a3d0SHeinrich Schuchardt	echo "$@"
17*02c3a3d0SHeinrich Schuchardt	exit 1
18*02c3a3d0SHeinrich Schuchardt}
19*02c3a3d0SHeinrich Schuchardt
20*02c3a3d0SHeinrich Schuchardttrap cleanup EXIT
21*02c3a3d0SHeinrich Schuchardt
22*02c3a3d0SHeinrich SchuchardtT=`mktemp` || die "cannot create temp file"
23*02c3a3d0SHeinrich Schuchardtcode=
24*02c3a3d0SHeinrich Schuchardtcont=
25*02c3a3d0SHeinrich Schuchardt
26*02c3a3d0SHeinrich Schuchardtwhile read i ; do
27*02c3a3d0SHeinrich Schuchardt
28*02c3a3d0SHeinrich Schuchardtcase "$i" in
29*02c3a3d0SHeinrich Schuchardt*Code:*)
30*02c3a3d0SHeinrich Schuchardt	code=$i
31*02c3a3d0SHeinrich Schuchardt	cont=yes
32*02c3a3d0SHeinrich Schuchardt	;;
33*02c3a3d0SHeinrich Schuchardt*)
34*02c3a3d0SHeinrich Schuchardt	[ -n "$cont" ] && {
35*02c3a3d0SHeinrich Schuchardt		xdump="$(echo $i | grep '^[[:xdigit:]<>[:space:]]\+$')"
36*02c3a3d0SHeinrich Schuchardt		if [ -n "$xdump" ]; then
37*02c3a3d0SHeinrich Schuchardt			code="$code $xdump"
38*02c3a3d0SHeinrich Schuchardt		else
39*02c3a3d0SHeinrich Schuchardt			cont=
40*02c3a3d0SHeinrich Schuchardt		fi
41*02c3a3d0SHeinrich Schuchardt	}
42*02c3a3d0SHeinrich Schuchardt	;;
43*02c3a3d0SHeinrich Schuchardtesac
44*02c3a3d0SHeinrich Schuchardt
45*02c3a3d0SHeinrich Schuchardtdone
46*02c3a3d0SHeinrich Schuchardt
47*02c3a3d0SHeinrich Schuchardtif [ -z "$code" ]; then
48*02c3a3d0SHeinrich Schuchardt	rm $T
49*02c3a3d0SHeinrich Schuchardt	exit
50*02c3a3d0SHeinrich Schuchardtfi
51*02c3a3d0SHeinrich Schuchardt
52*02c3a3d0SHeinrich Schuchardtecho $code
53*02c3a3d0SHeinrich Schuchardtcode=`echo $code | sed -e 's/.*Code: //'`
54*02c3a3d0SHeinrich Schuchardt
55*02c3a3d0SHeinrich Schuchardtwidth=`expr index "$code" ' '`
56*02c3a3d0SHeinrich Schuchardtwidth=$((($width-1)/2))
57*02c3a3d0SHeinrich Schuchardtcase $width in
58*02c3a3d0SHeinrich Schuchardt1) type=byte ;;
59*02c3a3d0SHeinrich Schuchardt2) type=2byte ;;
60*02c3a3d0SHeinrich Schuchardt4) type=4byte ;;
61*02c3a3d0SHeinrich Schuchardtesac
62*02c3a3d0SHeinrich Schuchardt
63*02c3a3d0SHeinrich Schuchardtdisas() {
64*02c3a3d0SHeinrich Schuchardt	${CROSS_COMPILE}as $AFLAGS -o $1.o $1.s > /dev/null 2>&1
65*02c3a3d0SHeinrich Schuchardt
66*02c3a3d0SHeinrich Schuchardt	if [ "$ARCH" = "arm" ]; then
67*02c3a3d0SHeinrich Schuchardt		if [ $width -eq 2 ]; then
68*02c3a3d0SHeinrich Schuchardt			OBJDUMPFLAGS="-M force-thumb"
69*02c3a3d0SHeinrich Schuchardt		fi
70*02c3a3d0SHeinrich Schuchardt
71*02c3a3d0SHeinrich Schuchardt		${CROSS_COMPILE}strip $1.o
72*02c3a3d0SHeinrich Schuchardt	fi
73*02c3a3d0SHeinrich Schuchardt
74*02c3a3d0SHeinrich Schuchardt	if [ "$ARCH" = "arm64" ]; then
75*02c3a3d0SHeinrich Schuchardt		if [ $width -eq 4 ]; then
76*02c3a3d0SHeinrich Schuchardt			type=inst
77*02c3a3d0SHeinrich Schuchardt		fi
78*02c3a3d0SHeinrich Schuchardt
79*02c3a3d0SHeinrich Schuchardt		${CROSS_COMPILE}strip $1.o
80*02c3a3d0SHeinrich Schuchardt	fi
81*02c3a3d0SHeinrich Schuchardt
82*02c3a3d0SHeinrich Schuchardt	${CROSS_COMPILE}objdump $OBJDUMPFLAGS -S $1.o | \
83*02c3a3d0SHeinrich Schuchardt		grep -v "/tmp\|Disassembly\|\.text\|^$" > $1.dis 2>&1
84*02c3a3d0SHeinrich Schuchardt}
85*02c3a3d0SHeinrich Schuchardt
86*02c3a3d0SHeinrich Schuchardtmarker=`expr index "$code" "\<"`
87*02c3a3d0SHeinrich Schuchardtif [ $marker -eq 0 ]; then
88*02c3a3d0SHeinrich Schuchardt	marker=`expr index "$code" "\("`
89*02c3a3d0SHeinrich Schuchardtfi
90*02c3a3d0SHeinrich Schuchardt
91*02c3a3d0SHeinrich Schuchardttouch $T.oo
92*02c3a3d0SHeinrich Schuchardtif [ $marker -ne 0 ]; then
93*02c3a3d0SHeinrich Schuchardt	echo All code >> $T.oo
94*02c3a3d0SHeinrich Schuchardt	echo ======== >> $T.oo
95*02c3a3d0SHeinrich Schuchardt	beforemark=`echo "$code"`
96*02c3a3d0SHeinrich Schuchardt	echo -n "	.$type 0x" > $T.s
97*02c3a3d0SHeinrich Schuchardt	echo $beforemark | sed -e 's/ /,0x/g; s/[<>()]//g' >> $T.s
98*02c3a3d0SHeinrich Schuchardt	disas $T
99*02c3a3d0SHeinrich Schuchardt	cat $T.dis >> $T.oo
100*02c3a3d0SHeinrich Schuchardt	rm -f $T.o $T.s $T.dis
101*02c3a3d0SHeinrich Schuchardt
102*02c3a3d0SHeinrich Schuchardt# and fix code at-and-after marker
103*02c3a3d0SHeinrich Schuchardt	code=`echo "$code" | cut -c$((${marker} + 1))-`
104*02c3a3d0SHeinrich Schuchardtfi
105*02c3a3d0SHeinrich Schuchardtecho Code starting with the faulting instruction  > $T.aa
106*02c3a3d0SHeinrich Schuchardtecho =========================================== >> $T.aa
107*02c3a3d0SHeinrich Schuchardtcode=`echo $code | sed -e 's/ [<(]/ /;s/[>)] / /;s/ /,0x/g; s/[>)]$//'`
108*02c3a3d0SHeinrich Schuchardtecho -n "	.$type 0x" > $T.s
109*02c3a3d0SHeinrich Schuchardtecho $code >> $T.s
110*02c3a3d0SHeinrich Schuchardtdisas $T
111*02c3a3d0SHeinrich Schuchardtcat $T.dis >> $T.aa
112*02c3a3d0SHeinrich Schuchardt
113*02c3a3d0SHeinrich Schuchardt# (lines of whole $T.oo) - (lines of $T.aa, i.e. "Code starting") + 3,
114*02c3a3d0SHeinrich Schuchardt# i.e. the title + the "===..=" line (sed is counting from 1, 0 address is
115*02c3a3d0SHeinrich Schuchardt# special)
116*02c3a3d0SHeinrich Schuchardtfaultlinenum=$(( $(wc -l $T.oo  | cut -d" " -f1) - \
117*02c3a3d0SHeinrich Schuchardt		 $(wc -l $T.aa  | cut -d" " -f1) + 3))
118*02c3a3d0SHeinrich Schuchardt
119*02c3a3d0SHeinrich Schuchardtfaultline=`cat $T.dis | head -1 | cut -d":" -f2-`
120*02c3a3d0SHeinrich Schuchardtfaultline=`echo "$faultline" | sed -e 's/\[/\\\[/g; s/\]/\\\]/g'`
121*02c3a3d0SHeinrich Schuchardt
122*02c3a3d0SHeinrich Schuchardtcat $T.oo | sed -e "${faultlinenum}s/^\(.*:\)\(.*\)/\1\*\2\t\t<-- trapping instruction/"
123*02c3a3d0SHeinrich Schuchardtecho
124*02c3a3d0SHeinrich Schuchardtcat $T.aa
125*02c3a3d0SHeinrich Schuchardtcleanup
126