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