dcecc6c70013e (Randy Dunlap 2007-07-15 23:41:15 -0700 1) #!/bin/sh
b24413180f560 (Greg Kroah-Hartman 2017-11-01 15:07:57 +0100 2) # SPDX-License-Identifier: GPL-2.0
dcecc6c70013e (Randy Dunlap 2007-07-15 23:41:15 -0700 3) # Disassemble the Code: line in Linux oopses
dcecc6c70013e (Randy Dunlap 2007-07-15 23:41:15 -0700 4) # usage: decodecode < oops.file
dcecc6c70013e (Randy Dunlap 2007-07-15 23:41:15 -0700 5) #
dcecc6c70013e (Randy Dunlap 2007-07-15 23:41:15 -0700 6) # options: set env. variable AFLAGS=options to pass options to "as";
dcecc6c70013e (Randy Dunlap 2007-07-15 23:41:15 -0700 7) # e.g., to decode an i386 oops on an x86_64 system, use:
dcecc6c70013e (Randy Dunlap 2007-07-15 23:41:15 -0700 8) # AFLAGS=--32 decodecode < 386.oops
d72e720a19393 (Borislav Petkov 2020-10-13 16:48:14 -0700 9) # PC=hex - the PC (program counter) the oops points to
dcecc6c70013e (Randy Dunlap 2007-07-15 23:41:15 -0700 10)
fa220d89ad050 (Randy Dunlap 2008-01-14 15:18:31 -0800 11) cleanup() {
5358db0b0e164 (Rabin Vincent 2010-01-05 20:27:58 +0530 12) rm -f $T $T.s $T.o $T.oo $T.aa $T.dis
fa220d89ad050 (Randy Dunlap 2008-01-14 15:18:31 -0800 13) exit 1
fa220d89ad050 (Randy Dunlap 2008-01-14 15:18:31 -0800 14) }
fa220d89ad050 (Randy Dunlap 2008-01-14 15:18:31 -0800 15)
fa220d89ad050 (Randy Dunlap 2008-01-14 15:18:31 -0800 16) die() {
fa220d89ad050 (Randy Dunlap 2008-01-14 15:18:31 -0800 17) echo "$@"
fa220d89ad050 (Randy Dunlap 2008-01-14 15:18:31 -0800 18) exit 1
fa220d89ad050 (Randy Dunlap 2008-01-14 15:18:31 -0800 19) }
fa220d89ad050 (Randy Dunlap 2008-01-14 15:18:31 -0800 20)
fa220d89ad050 (Randy Dunlap 2008-01-14 15:18:31 -0800 21) trap cleanup EXIT
fa220d89ad050 (Randy Dunlap 2008-01-14 15:18:31 -0800 22)
fa220d89ad050 (Randy Dunlap 2008-01-14 15:18:31 -0800 23) T=`mktemp` || die "cannot create temp file"
dcecc6c70013e (Randy Dunlap 2007-07-15 23:41:15 -0700 24) code=
7e68b36145788 (Andy Shevchenko 2018-01-31 16:14:10 -0800 25) cont=
dcecc6c70013e (Randy Dunlap 2007-07-15 23:41:15 -0700 26)
dcecc6c70013e (Randy Dunlap 2007-07-15 23:41:15 -0700 27) while read i ; do
dcecc6c70013e (Randy Dunlap 2007-07-15 23:41:15 -0700 28)
dcecc6c70013e (Randy Dunlap 2007-07-15 23:41:15 -0700 29) case "$i" in
dcecc6c70013e (Randy Dunlap 2007-07-15 23:41:15 -0700 30) *Code:*)
dcecc6c70013e (Randy Dunlap 2007-07-15 23:41:15 -0700 31) code=$i
7e68b36145788 (Andy Shevchenko 2018-01-31 16:14:10 -0800 32) cont=yes
7e68b36145788 (Andy Shevchenko 2018-01-31 16:14:10 -0800 33) ;;
7e68b36145788 (Andy Shevchenko 2018-01-31 16:14:10 -0800 34) *)
7e68b36145788 (Andy Shevchenko 2018-01-31 16:14:10 -0800 35) [ -n "$cont" ] && {
7e68b36145788 (Andy Shevchenko 2018-01-31 16:14:10 -0800 36) xdump="$(echo $i | grep '^[[:xdigit:]<>[:space:]]\+$')"
7e68b36145788 (Andy Shevchenko 2018-01-31 16:14:10 -0800 37) if [ -n "$xdump" ]; then
7e68b36145788 (Andy Shevchenko 2018-01-31 16:14:10 -0800 38) code="$code $xdump"
7e68b36145788 (Andy Shevchenko 2018-01-31 16:14:10 -0800 39) else
7e68b36145788 (Andy Shevchenko 2018-01-31 16:14:10 -0800 40) cont=
7e68b36145788 (Andy Shevchenko 2018-01-31 16:14:10 -0800 41) fi
7e68b36145788 (Andy Shevchenko 2018-01-31 16:14:10 -0800 42) }
dcecc6c70013e (Randy Dunlap 2007-07-15 23:41:15 -0700 43) ;;
dcecc6c70013e (Randy Dunlap 2007-07-15 23:41:15 -0700 44) esac
dcecc6c70013e (Randy Dunlap 2007-07-15 23:41:15 -0700 45)
dcecc6c70013e (Randy Dunlap 2007-07-15 23:41:15 -0700 46) done
dcecc6c70013e (Randy Dunlap 2007-07-15 23:41:15 -0700 47)
dcecc6c70013e (Randy Dunlap 2007-07-15 23:41:15 -0700 48) if [ -z "$code" ]; then
fa220d89ad050 (Randy Dunlap 2008-01-14 15:18:31 -0800 49) rm $T
dcecc6c70013e (Randy Dunlap 2007-07-15 23:41:15 -0700 50) exit
dcecc6c70013e (Randy Dunlap 2007-07-15 23:41:15 -0700 51) fi
dcecc6c70013e (Randy Dunlap 2007-07-15 23:41:15 -0700 52)
dcecc6c70013e (Randy Dunlap 2007-07-15 23:41:15 -0700 53) echo $code
dcecc6c70013e (Randy Dunlap 2007-07-15 23:41:15 -0700 54) code=`echo $code | sed -e 's/.*Code: //'`
dcecc6c70013e (Randy Dunlap 2007-07-15 23:41:15 -0700 55)
5358db0b0e164 (Rabin Vincent 2010-01-05 20:27:58 +0530 56) width=`expr index "$code" ' '`
b396aa03084b5 (Rabin Vincent 2010-06-03 22:48:12 +0530 57) width=$((($width-1)/2))
5358db0b0e164 (Rabin Vincent 2010-01-05 20:27:58 +0530 58) case $width in
5358db0b0e164 (Rabin Vincent 2010-01-05 20:27:58 +0530 59) 1) type=byte ;;
5358db0b0e164 (Rabin Vincent 2010-01-05 20:27:58 +0530 60) 2) type=2byte ;;
5358db0b0e164 (Rabin Vincent 2010-01-05 20:27:58 +0530 61) 4) type=4byte ;;
5358db0b0e164 (Rabin Vincent 2010-01-05 20:27:58 +0530 62) esac
5358db0b0e164 (Rabin Vincent 2010-01-05 20:27:58 +0530 63)
c5cfb62f2bdf5 (Marc Zyngier 2018-12-28 00:31:21 -0800 64) if [ -z "$ARCH" ]; then
c5cfb62f2bdf5 (Marc Zyngier 2018-12-28 00:31:21 -0800 65) case `uname -m` in
c5cfb62f2bdf5 (Marc Zyngier 2018-12-28 00:31:21 -0800 66) aarch64*) ARCH=arm64 ;;
c5cfb62f2bdf5 (Marc Zyngier 2018-12-28 00:31:21 -0800 67) arm*) ARCH=arm ;;
c5cfb62f2bdf5 (Marc Zyngier 2018-12-28 00:31:21 -0800 68) esac
c5cfb62f2bdf5 (Marc Zyngier 2018-12-28 00:31:21 -0800 69) fi
c5cfb62f2bdf5 (Marc Zyngier 2018-12-28 00:31:21 -0800 70)
d72e720a19393 (Borislav Petkov 2020-10-13 16:48:14 -0700 71) # Params: (tmp_file, pc_sub)
5358db0b0e164 (Rabin Vincent 2010-01-05 20:27:58 +0530 72) disas() {
d72e720a19393 (Borislav Petkov 2020-10-13 16:48:14 -0700 73) t=$1
d72e720a19393 (Borislav Petkov 2020-10-13 16:48:14 -0700 74) pc_sub=$2
d72e720a19393 (Borislav Petkov 2020-10-13 16:48:14 -0700 75)
d72e720a19393 (Borislav Petkov 2020-10-13 16:48:14 -0700 76) ${CROSS_COMPILE}as $AFLAGS -o $t.o $t.s > /dev/null 2>&1
5358db0b0e164 (Rabin Vincent 2010-01-05 20:27:58 +0530 77)
b396aa03084b5 (Rabin Vincent 2010-06-03 22:48:12 +0530 78) if [ "$ARCH" = "arm" ]; then
b396aa03084b5 (Rabin Vincent 2010-06-03 22:48:12 +0530 79) if [ $width -eq 2 ]; then
5358db0b0e164 (Rabin Vincent 2010-01-05 20:27:58 +0530 80) OBJDUMPFLAGS="-M force-thumb"
5358db0b0e164 (Rabin Vincent 2010-01-05 20:27:58 +0530 81) fi
5358db0b0e164 (Rabin Vincent 2010-01-05 20:27:58 +0530 82)
d72e720a19393 (Borislav Petkov 2020-10-13 16:48:14 -0700 83) ${CROSS_COMPILE}strip $t.o
5358db0b0e164 (Rabin Vincent 2010-01-05 20:27:58 +0530 84) fi
5358db0b0e164 (Rabin Vincent 2010-01-05 20:27:58 +0530 85)
be9fa663d325a (Will Deacon 2018-01-18 16:33:57 -0800 86) if [ "$ARCH" = "arm64" ]; then
be9fa663d325a (Will Deacon 2018-01-18 16:33:57 -0800 87) if [ $width -eq 4 ]; then
be9fa663d325a (Will Deacon 2018-01-18 16:33:57 -0800 88) type=inst
be9fa663d325a (Will Deacon 2018-01-18 16:33:57 -0800 89) fi
be9fa663d325a (Will Deacon 2018-01-18 16:33:57 -0800 90)
d72e720a19393 (Borislav Petkov 2020-10-13 16:48:14 -0700 91) ${CROSS_COMPILE}strip $t.o
be9fa663d325a (Will Deacon 2018-01-18 16:33:57 -0800 92) fi
be9fa663d325a (Will Deacon 2018-01-18 16:33:57 -0800 93)
d72e720a19393 (Borislav Petkov 2020-10-13 16:48:14 -0700 94) if [ $pc_sub -ne 0 ]; then
d72e720a19393 (Borislav Petkov 2020-10-13 16:48:14 -0700 95) if [ $PC ]; then
d72e720a19393 (Borislav Petkov 2020-10-13 16:48:14 -0700 96) adj_vma=$(( $PC - $pc_sub ))
d72e720a19393 (Borislav Petkov 2020-10-13 16:48:14 -0700 97) OBJDUMPFLAGS="$OBJDUMPFLAGS --adjust-vma=$adj_vma"
d72e720a19393 (Borislav Petkov 2020-10-13 16:48:14 -0700 98) fi
d72e720a19393 (Borislav Petkov 2020-10-13 16:48:14 -0700 99) fi
d72e720a19393 (Borislav Petkov 2020-10-13 16:48:14 -0700 100)
d72e720a19393 (Borislav Petkov 2020-10-13 16:48:14 -0700 101) ${CROSS_COMPILE}objdump $OBJDUMPFLAGS -S $t.o | \
d72e720a19393 (Borislav Petkov 2020-10-13 16:48:14 -0700 102) grep -v "/tmp\|Disassembly\|\.text\|^$" > $t.dis 2>&1
5358db0b0e164 (Rabin Vincent 2010-01-05 20:27:58 +0530 103) }
5358db0b0e164 (Rabin Vincent 2010-01-05 20:27:58 +0530 104)
dcecc6c70013e (Randy Dunlap 2007-07-15 23:41:15 -0700 105) marker=`expr index "$code" "\<"`
dcecc6c70013e (Randy Dunlap 2007-07-15 23:41:15 -0700 106) if [ $marker -eq 0 ]; then
dcecc6c70013e (Randy Dunlap 2007-07-15 23:41:15 -0700 107) marker=`expr index "$code" "\("`
dcecc6c70013e (Randy Dunlap 2007-07-15 23:41:15 -0700 108) fi
dcecc6c70013e (Randy Dunlap 2007-07-15 23:41:15 -0700 109)
d72e720a19393 (Borislav Petkov 2020-10-13 16:48:14 -0700 110)
846442c8ddc02 (Arjan van de Ven 2008-12-01 14:21:06 -0800 111) touch $T.oo
dcecc6c70013e (Randy Dunlap 2007-07-15 23:41:15 -0700 112) if [ $marker -ne 0 ]; then
d72e720a19393 (Borislav Petkov 2020-10-13 16:48:14 -0700 113) # 2 opcode bytes and a single space
d72e720a19393 (Borislav Petkov 2020-10-13 16:48:14 -0700 114) pc_sub=$(( $marker / 3 ))
846442c8ddc02 (Arjan van de Ven 2008-12-01 14:21:06 -0800 115) echo All code >> $T.oo
846442c8ddc02 (Arjan van de Ven 2008-12-01 14:21:06 -0800 116) echo ======== >> $T.oo
846442c8ddc02 (Arjan van de Ven 2008-12-01 14:21:06 -0800 117) beforemark=`echo "$code"`
5358db0b0e164 (Rabin Vincent 2010-01-05 20:27:58 +0530 118) echo -n " .$type 0x" > $T.s
5358db0b0e164 (Rabin Vincent 2010-01-05 20:27:58 +0530 119) echo $beforemark | sed -e 's/ /,0x/g; s/[<>()]//g' >> $T.s
d72e720a19393 (Borislav Petkov 2020-10-13 16:48:14 -0700 120) disas $T $pc_sub
5358db0b0e164 (Rabin Vincent 2010-01-05 20:27:58 +0530 121) cat $T.dis >> $T.oo
5358db0b0e164 (Rabin Vincent 2010-01-05 20:27:58 +0530 122) rm -f $T.o $T.s $T.dis
dcecc6c70013e (Randy Dunlap 2007-07-15 23:41:15 -0700 123)
dcecc6c70013e (Randy Dunlap 2007-07-15 23:41:15 -0700 124) # and fix code at-and-after marker
dcecc6c70013e (Randy Dunlap 2007-07-15 23:41:15 -0700 125) code=`echo "$code" | cut -c$((${marker} + 1))-`
dcecc6c70013e (Randy Dunlap 2007-07-15 23:41:15 -0700 126) fi
846442c8ddc02 (Arjan van de Ven 2008-12-01 14:21:06 -0800 127) echo Code starting with the faulting instruction > $T.aa
846442c8ddc02 (Arjan van de Ven 2008-12-01 14:21:06 -0800 128) echo =========================================== >> $T.aa
5358db0b0e164 (Rabin Vincent 2010-01-05 20:27:58 +0530 129) code=`echo $code | sed -e 's/ [<(]/ /;s/[>)] / /;s/ /,0x/g; s/[>)]$//'`
5358db0b0e164 (Rabin Vincent 2010-01-05 20:27:58 +0530 130) echo -n " .$type 0x" > $T.s
dcecc6c70013e (Randy Dunlap 2007-07-15 23:41:15 -0700 131) echo $code >> $T.s
d72e720a19393 (Borislav Petkov 2020-10-13 16:48:14 -0700 132) disas $T 0
5358db0b0e164 (Rabin Vincent 2010-01-05 20:27:58 +0530 133) cat $T.dis >> $T.aa
846442c8ddc02 (Arjan van de Ven 2008-12-01 14:21:06 -0800 134)
18ff44b189e2a (Borislav Petkov 2013-04-29 15:05:54 -0700 135) # (lines of whole $T.oo) - (lines of $T.aa, i.e. "Code starting") + 3,
18ff44b189e2a (Borislav Petkov 2013-04-29 15:05:54 -0700 136) # i.e. the title + the "===..=" line (sed is counting from 1, 0 address is
18ff44b189e2a (Borislav Petkov 2013-04-29 15:05:54 -0700 137) # special)
18ff44b189e2a (Borislav Petkov 2013-04-29 15:05:54 -0700 138) faultlinenum=$(( $(wc -l $T.oo | cut -d" " -f1) - \
18ff44b189e2a (Borislav Petkov 2013-04-29 15:05:54 -0700 139) $(wc -l $T.aa | cut -d" " -f1) + 3))
18ff44b189e2a (Borislav Petkov 2013-04-29 15:05:54 -0700 140)
2a95e37c128d1 (Borislav Petkov 2012-08-15 13:00:51 +0200 141) faultline=`cat $T.dis | head -1 | cut -d":" -f2-`
5358db0b0e164 (Rabin Vincent 2010-01-05 20:27:58 +0530 142) faultline=`echo "$faultline" | sed -e 's/\[/\\\[/g; s/\]/\\\]/g'`
846442c8ddc02 (Arjan van de Ven 2008-12-01 14:21:06 -0800 143)
e08df079b23e2 (Ivan Delalande 2020-05-07 18:35:53 -0700 144) cat $T.oo | sed -e "${faultlinenum}s/^\([^:]*:\)\(.*\)/\1\*\2\t\t<-- trapping instruction/"
846442c8ddc02 (Arjan van de Ven 2008-12-01 14:21:06 -0800 145) echo
846442c8ddc02 (Arjan van de Ven 2008-12-01 14:21:06 -0800 146) cat $T.aa
846442c8ddc02 (Arjan van de Ven 2008-12-01 14:21:06 -0800 147) cleanup