1dcecc6c7SRandy Dunlap#!/bin/sh 2b2441318SGreg Kroah-Hartman# SPDX-License-Identifier: GPL-2.0 3dcecc6c7SRandy Dunlap# Disassemble the Code: line in Linux oopses 4dcecc6c7SRandy Dunlap# usage: decodecode < oops.file 5dcecc6c7SRandy Dunlap# 6dcecc6c7SRandy Dunlap# options: set env. variable AFLAGS=options to pass options to "as"; 7dcecc6c7SRandy Dunlap# e.g., to decode an i386 oops on an x86_64 system, use: 8dcecc6c7SRandy Dunlap# AFLAGS=--32 decodecode < 386.oops 9dcecc6c7SRandy Dunlap 10fa220d89SRandy Dunlapcleanup() { 115358db0bSRabin Vincent rm -f $T $T.s $T.o $T.oo $T.aa $T.dis 12fa220d89SRandy Dunlap exit 1 13fa220d89SRandy Dunlap} 14fa220d89SRandy Dunlap 15fa220d89SRandy Dunlapdie() { 16fa220d89SRandy Dunlap echo "$@" 17fa220d89SRandy Dunlap exit 1 18fa220d89SRandy Dunlap} 19fa220d89SRandy Dunlap 20fa220d89SRandy Dunlaptrap cleanup EXIT 21fa220d89SRandy Dunlap 22fa220d89SRandy DunlapT=`mktemp` || die "cannot create temp file" 23dcecc6c7SRandy Dunlapcode= 247e68b361SAndy Shevchenkocont= 25dcecc6c7SRandy Dunlap 26dcecc6c7SRandy Dunlapwhile read i ; do 27dcecc6c7SRandy Dunlap 28dcecc6c7SRandy Dunlapcase "$i" in 29dcecc6c7SRandy Dunlap*Code:*) 30dcecc6c7SRandy Dunlap code=$i 317e68b361SAndy Shevchenko cont=yes 327e68b361SAndy Shevchenko ;; 337e68b361SAndy Shevchenko*) 347e68b361SAndy Shevchenko [ -n "$cont" ] && { 357e68b361SAndy Shevchenko xdump="$(echo $i | grep '^[[:xdigit:]<>[:space:]]\+$')" 367e68b361SAndy Shevchenko if [ -n "$xdump" ]; then 377e68b361SAndy Shevchenko code="$code $xdump" 387e68b361SAndy Shevchenko else 397e68b361SAndy Shevchenko cont= 407e68b361SAndy Shevchenko fi 417e68b361SAndy Shevchenko } 42dcecc6c7SRandy Dunlap ;; 43dcecc6c7SRandy Dunlapesac 44dcecc6c7SRandy Dunlap 45dcecc6c7SRandy Dunlapdone 46dcecc6c7SRandy Dunlap 47dcecc6c7SRandy Dunlapif [ -z "$code" ]; then 48fa220d89SRandy Dunlap rm $T 49dcecc6c7SRandy Dunlap exit 50dcecc6c7SRandy Dunlapfi 51dcecc6c7SRandy Dunlap 52dcecc6c7SRandy Dunlapecho $code 53dcecc6c7SRandy Dunlapcode=`echo $code | sed -e 's/.*Code: //'` 54dcecc6c7SRandy Dunlap 555358db0bSRabin Vincentwidth=`expr index "$code" ' '` 56b396aa03SRabin Vincentwidth=$((($width-1)/2)) 575358db0bSRabin Vincentcase $width in 585358db0bSRabin Vincent1) type=byte ;; 595358db0bSRabin Vincent2) type=2byte ;; 605358db0bSRabin Vincent4) type=4byte ;; 615358db0bSRabin Vincentesac 625358db0bSRabin Vincent 63c5cfb62fSMarc Zyngierif [ -z "$ARCH" ]; then 64c5cfb62fSMarc Zyngier case `uname -m` in 65c5cfb62fSMarc Zyngier aarch64*) ARCH=arm64 ;; 66c5cfb62fSMarc Zyngier arm*) ARCH=arm ;; 67c5cfb62fSMarc Zyngier esac 68c5cfb62fSMarc Zyngierfi 69c5cfb62fSMarc Zyngier 705358db0bSRabin Vincentdisas() { 71b396aa03SRabin Vincent ${CROSS_COMPILE}as $AFLAGS -o $1.o $1.s > /dev/null 2>&1 725358db0bSRabin Vincent 73b396aa03SRabin Vincent if [ "$ARCH" = "arm" ]; then 74b396aa03SRabin Vincent if [ $width -eq 2 ]; then 755358db0bSRabin Vincent OBJDUMPFLAGS="-M force-thumb" 765358db0bSRabin Vincent fi 775358db0bSRabin Vincent 785358db0bSRabin Vincent ${CROSS_COMPILE}strip $1.o 795358db0bSRabin Vincent fi 805358db0bSRabin Vincent 81be9fa663SWill Deacon if [ "$ARCH" = "arm64" ]; then 82be9fa663SWill Deacon if [ $width -eq 4 ]; then 83be9fa663SWill Deacon type=inst 84be9fa663SWill Deacon fi 85be9fa663SWill Deacon 86be9fa663SWill Deacon ${CROSS_COMPILE}strip $1.o 87be9fa663SWill Deacon fi 88be9fa663SWill Deacon 895358db0bSRabin Vincent ${CROSS_COMPILE}objdump $OBJDUMPFLAGS -S $1.o | \ 90b396aa03SRabin Vincent grep -v "/tmp\|Disassembly\|\.text\|^$" > $1.dis 2>&1 915358db0bSRabin Vincent} 925358db0bSRabin Vincent 93dcecc6c7SRandy Dunlapmarker=`expr index "$code" "\<"` 94dcecc6c7SRandy Dunlapif [ $marker -eq 0 ]; then 95dcecc6c7SRandy Dunlap marker=`expr index "$code" "\("` 96dcecc6c7SRandy Dunlapfi 97dcecc6c7SRandy Dunlap 98846442c8SArjan van de Ventouch $T.oo 99dcecc6c7SRandy Dunlapif [ $marker -ne 0 ]; then 100846442c8SArjan van de Ven echo All code >> $T.oo 101846442c8SArjan van de Ven echo ======== >> $T.oo 102846442c8SArjan van de Ven beforemark=`echo "$code"` 1035358db0bSRabin Vincent echo -n " .$type 0x" > $T.s 1045358db0bSRabin Vincent echo $beforemark | sed -e 's/ /,0x/g; s/[<>()]//g' >> $T.s 1055358db0bSRabin Vincent disas $T 1065358db0bSRabin Vincent cat $T.dis >> $T.oo 1075358db0bSRabin Vincent rm -f $T.o $T.s $T.dis 108dcecc6c7SRandy Dunlap 109dcecc6c7SRandy Dunlap# and fix code at-and-after marker 110dcecc6c7SRandy Dunlap code=`echo "$code" | cut -c$((${marker} + 1))-` 111dcecc6c7SRandy Dunlapfi 112846442c8SArjan van de Venecho Code starting with the faulting instruction > $T.aa 113846442c8SArjan van de Venecho =========================================== >> $T.aa 1145358db0bSRabin Vincentcode=`echo $code | sed -e 's/ [<(]/ /;s/[>)] / /;s/ /,0x/g; s/[>)]$//'` 1155358db0bSRabin Vincentecho -n " .$type 0x" > $T.s 116dcecc6c7SRandy Dunlapecho $code >> $T.s 1175358db0bSRabin Vincentdisas $T 1185358db0bSRabin Vincentcat $T.dis >> $T.aa 119846442c8SArjan van de Ven 12018ff44b1SBorislav Petkov# (lines of whole $T.oo) - (lines of $T.aa, i.e. "Code starting") + 3, 12118ff44b1SBorislav Petkov# i.e. the title + the "===..=" line (sed is counting from 1, 0 address is 12218ff44b1SBorislav Petkov# special) 12318ff44b1SBorislav Petkovfaultlinenum=$(( $(wc -l $T.oo | cut -d" " -f1) - \ 12418ff44b1SBorislav Petkov $(wc -l $T.aa | cut -d" " -f1) + 3)) 12518ff44b1SBorislav Petkov 1262a95e37cSBorislav Petkovfaultline=`cat $T.dis | head -1 | cut -d":" -f2-` 1275358db0bSRabin Vincentfaultline=`echo "$faultline" | sed -e 's/\[/\\\[/g; s/\]/\\\]/g'` 128846442c8SArjan van de Ven 129*e08df079SIvan Delalandecat $T.oo | sed -e "${faultlinenum}s/^\([^:]*:\)\(.*\)/\1\*\2\t\t<-- trapping instruction/" 130846442c8SArjan van de Venecho 131846442c8SArjan van de Vencat $T.aa 132846442c8SArjan van de Vencleanup 133