18c2ecf20Sopenharmony_ci#!/bin/sh 28c2ecf20Sopenharmony_ci# SPDX-License-Identifier: GPL-2.0 38c2ecf20Sopenharmony_ci# Disassemble the Code: line in Linux oopses 48c2ecf20Sopenharmony_ci# usage: decodecode < oops.file 58c2ecf20Sopenharmony_ci# 68c2ecf20Sopenharmony_ci# options: set env. variable AFLAGS=options to pass options to "as"; 78c2ecf20Sopenharmony_ci# e.g., to decode an i386 oops on an x86_64 system, use: 88c2ecf20Sopenharmony_ci# AFLAGS=--32 decodecode < 386.oops 98c2ecf20Sopenharmony_ci# PC=hex - the PC (program counter) the oops points to 108c2ecf20Sopenharmony_ci 118c2ecf20Sopenharmony_cicleanup() { 128c2ecf20Sopenharmony_ci rm -f $T $T.s $T.o $T.oo $T.aa $T.dis 138c2ecf20Sopenharmony_ci exit 1 148c2ecf20Sopenharmony_ci} 158c2ecf20Sopenharmony_ci 168c2ecf20Sopenharmony_cidie() { 178c2ecf20Sopenharmony_ci echo "$@" 188c2ecf20Sopenharmony_ci exit 1 198c2ecf20Sopenharmony_ci} 208c2ecf20Sopenharmony_ci 218c2ecf20Sopenharmony_citrap cleanup EXIT 228c2ecf20Sopenharmony_ci 238c2ecf20Sopenharmony_ciT=`mktemp` || die "cannot create temp file" 248c2ecf20Sopenharmony_cicode= 258c2ecf20Sopenharmony_cicont= 268c2ecf20Sopenharmony_ci 278c2ecf20Sopenharmony_ciwhile read i ; do 288c2ecf20Sopenharmony_ci 298c2ecf20Sopenharmony_cicase "$i" in 308c2ecf20Sopenharmony_ci*Code:*) 318c2ecf20Sopenharmony_ci code=$i 328c2ecf20Sopenharmony_ci cont=yes 338c2ecf20Sopenharmony_ci ;; 348c2ecf20Sopenharmony_ci*) 358c2ecf20Sopenharmony_ci [ -n "$cont" ] && { 368c2ecf20Sopenharmony_ci xdump="$(echo $i | grep '^[[:xdigit:]<>[:space:]]\+$')" 378c2ecf20Sopenharmony_ci if [ -n "$xdump" ]; then 388c2ecf20Sopenharmony_ci code="$code $xdump" 398c2ecf20Sopenharmony_ci else 408c2ecf20Sopenharmony_ci cont= 418c2ecf20Sopenharmony_ci fi 428c2ecf20Sopenharmony_ci } 438c2ecf20Sopenharmony_ci ;; 448c2ecf20Sopenharmony_ciesac 458c2ecf20Sopenharmony_ci 468c2ecf20Sopenharmony_cidone 478c2ecf20Sopenharmony_ci 488c2ecf20Sopenharmony_ciif [ -z "$code" ]; then 498c2ecf20Sopenharmony_ci rm $T 508c2ecf20Sopenharmony_ci exit 518c2ecf20Sopenharmony_cifi 528c2ecf20Sopenharmony_ci 538c2ecf20Sopenharmony_ciecho $code 548c2ecf20Sopenharmony_cicode=`echo $code | sed -e 's/.*Code: //'` 558c2ecf20Sopenharmony_ci 568c2ecf20Sopenharmony_ciwidth=`expr index "$code" ' '` 578c2ecf20Sopenharmony_ciwidth=$((($width-1)/2)) 588c2ecf20Sopenharmony_cicase $width in 598c2ecf20Sopenharmony_ci1) type=byte ;; 608c2ecf20Sopenharmony_ci2) type=2byte ;; 618c2ecf20Sopenharmony_ci4) type=4byte ;; 628c2ecf20Sopenharmony_ciesac 638c2ecf20Sopenharmony_ci 648c2ecf20Sopenharmony_ciif [ -z "$ARCH" ]; then 658c2ecf20Sopenharmony_ci case `uname -m` in 668c2ecf20Sopenharmony_ci aarch64*) ARCH=arm64 ;; 678c2ecf20Sopenharmony_ci arm*) ARCH=arm ;; 688c2ecf20Sopenharmony_ci esac 698c2ecf20Sopenharmony_cifi 708c2ecf20Sopenharmony_ci 718c2ecf20Sopenharmony_ci# Params: (tmp_file, pc_sub) 728c2ecf20Sopenharmony_cidisas() { 738c2ecf20Sopenharmony_ci t=$1 748c2ecf20Sopenharmony_ci pc_sub=$2 758c2ecf20Sopenharmony_ci 768c2ecf20Sopenharmony_ci ${CROSS_COMPILE}as $AFLAGS -o $t.o $t.s > /dev/null 2>&1 778c2ecf20Sopenharmony_ci 788c2ecf20Sopenharmony_ci if [ "$ARCH" = "arm" ]; then 798c2ecf20Sopenharmony_ci if [ $width -eq 2 ]; then 808c2ecf20Sopenharmony_ci OBJDUMPFLAGS="-M force-thumb" 818c2ecf20Sopenharmony_ci fi 828c2ecf20Sopenharmony_ci 838c2ecf20Sopenharmony_ci ${CROSS_COMPILE}strip $t.o 848c2ecf20Sopenharmony_ci fi 858c2ecf20Sopenharmony_ci 868c2ecf20Sopenharmony_ci if [ "$ARCH" = "arm64" ]; then 878c2ecf20Sopenharmony_ci if [ $width -eq 4 ]; then 888c2ecf20Sopenharmony_ci type=inst 898c2ecf20Sopenharmony_ci fi 908c2ecf20Sopenharmony_ci 918c2ecf20Sopenharmony_ci ${CROSS_COMPILE}strip $t.o 928c2ecf20Sopenharmony_ci fi 938c2ecf20Sopenharmony_ci 948c2ecf20Sopenharmony_ci if [ $pc_sub -ne 0 ]; then 958c2ecf20Sopenharmony_ci if [ $PC ]; then 968c2ecf20Sopenharmony_ci adj_vma=$(( $PC - $pc_sub )) 978c2ecf20Sopenharmony_ci OBJDUMPFLAGS="$OBJDUMPFLAGS --adjust-vma=$adj_vma" 988c2ecf20Sopenharmony_ci fi 998c2ecf20Sopenharmony_ci fi 1008c2ecf20Sopenharmony_ci 1018c2ecf20Sopenharmony_ci ${CROSS_COMPILE}objdump $OBJDUMPFLAGS -S $t.o | \ 1028c2ecf20Sopenharmony_ci grep -v "/tmp\|Disassembly\|\.text\|^$" > $t.dis 2>&1 1038c2ecf20Sopenharmony_ci} 1048c2ecf20Sopenharmony_ci 1058c2ecf20Sopenharmony_cimarker=`expr index "$code" "\<"` 1068c2ecf20Sopenharmony_ciif [ $marker -eq 0 ]; then 1078c2ecf20Sopenharmony_ci marker=`expr index "$code" "\("` 1088c2ecf20Sopenharmony_cifi 1098c2ecf20Sopenharmony_ci 1108c2ecf20Sopenharmony_ci 1118c2ecf20Sopenharmony_citouch $T.oo 1128c2ecf20Sopenharmony_ciif [ $marker -ne 0 ]; then 1138c2ecf20Sopenharmony_ci # 2 opcode bytes and a single space 1148c2ecf20Sopenharmony_ci pc_sub=$(( $marker / 3 )) 1158c2ecf20Sopenharmony_ci echo All code >> $T.oo 1168c2ecf20Sopenharmony_ci echo ======== >> $T.oo 1178c2ecf20Sopenharmony_ci beforemark=`echo "$code"` 1188c2ecf20Sopenharmony_ci echo -n " .$type 0x" > $T.s 1198c2ecf20Sopenharmony_ci echo $beforemark | sed -e 's/ /,0x/g; s/[<>()]//g' >> $T.s 1208c2ecf20Sopenharmony_ci disas $T $pc_sub 1218c2ecf20Sopenharmony_ci cat $T.dis >> $T.oo 1228c2ecf20Sopenharmony_ci rm -f $T.o $T.s $T.dis 1238c2ecf20Sopenharmony_ci 1248c2ecf20Sopenharmony_ci# and fix code at-and-after marker 1258c2ecf20Sopenharmony_ci code=`echo "$code" | cut -c$((${marker} + 1))-` 1268c2ecf20Sopenharmony_cifi 1278c2ecf20Sopenharmony_ciecho Code starting with the faulting instruction > $T.aa 1288c2ecf20Sopenharmony_ciecho =========================================== >> $T.aa 1298c2ecf20Sopenharmony_cicode=`echo $code | sed -e 's/ [<(]/ /;s/[>)] / /;s/ /,0x/g; s/[>)]$//'` 1308c2ecf20Sopenharmony_ciecho -n " .$type 0x" > $T.s 1318c2ecf20Sopenharmony_ciecho $code >> $T.s 1328c2ecf20Sopenharmony_cidisas $T 0 1338c2ecf20Sopenharmony_cicat $T.dis >> $T.aa 1348c2ecf20Sopenharmony_ci 1358c2ecf20Sopenharmony_ci# (lines of whole $T.oo) - (lines of $T.aa, i.e. "Code starting") + 3, 1368c2ecf20Sopenharmony_ci# i.e. the title + the "===..=" line (sed is counting from 1, 0 address is 1378c2ecf20Sopenharmony_ci# special) 1388c2ecf20Sopenharmony_cifaultlinenum=$(( $(wc -l $T.oo | cut -d" " -f1) - \ 1398c2ecf20Sopenharmony_ci $(wc -l $T.aa | cut -d" " -f1) + 3)) 1408c2ecf20Sopenharmony_ci 1418c2ecf20Sopenharmony_cifaultline=`cat $T.dis | head -1 | cut -d":" -f2-` 1428c2ecf20Sopenharmony_cifaultline=`echo "$faultline" | sed -e 's/\[/\\\[/g; s/\]/\\\]/g'` 1438c2ecf20Sopenharmony_ci 1448c2ecf20Sopenharmony_cicat $T.oo | sed -e "${faultlinenum}s/^\([^:]*:\)\(.*\)/\1\*\2\t\t<-- trapping instruction/" 1458c2ecf20Sopenharmony_ciecho 1468c2ecf20Sopenharmony_cicat $T.aa 1478c2ecf20Sopenharmony_cicleanup 148