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
  63disas() {
  64        ${CROSS_COMPILE}as $AFLAGS -o $1.o $1.s > /dev/null 2>&1
  65
  66        if [ "$ARCH" = "arm" ]; then
  67                if [ $width -eq 2 ]; then
  68                        OBJDUMPFLAGS="-M force-thumb"
  69                fi
  70
  71                ${CROSS_COMPILE}strip $1.o
  72        fi
  73
  74        if [ "$ARCH" = "arm64" ]; then
  75                if [ $width -eq 4 ]; then
  76                        type=inst
  77                fi
  78
  79                ${CROSS_COMPILE}strip $1.o
  80        fi
  81
  82        ${CROSS_COMPILE}objdump $OBJDUMPFLAGS -S $1.o | \
  83                grep -v "/tmp\|Disassembly\|\.text\|^$" > $1.dis 2>&1
  84}
  85
  86marker=`expr index "$code" "\<"`
  87if [ $marker -eq 0 ]; then
  88        marker=`expr index "$code" "\("`
  89fi
  90
  91touch $T.oo
  92if [ $marker -ne 0 ]; then
  93        echo All code >> $T.oo
  94        echo ======== >> $T.oo
  95        beforemark=`echo "$code"`
  96        echo -n "       .$type 0x" > $T.s
  97        echo $beforemark | sed -e 's/ /,0x/g; s/[<>()]//g' >> $T.s
  98        disas $T
  99        cat $T.dis >> $T.oo
 100        rm -f $T.o $T.s $T.dis
 101
 102# and fix code at-and-after marker
 103        code=`echo "$code" | cut -c$((${marker} + 1))-`
 104fi
 105echo Code starting with the faulting instruction  > $T.aa
 106echo =========================================== >> $T.aa
 107code=`echo $code | sed -e 's/ [<(]/ /;s/[>)] / /;s/ /,0x/g; s/[>)]$//'`
 108echo -n "       .$type 0x" > $T.s
 109echo $code >> $T.s
 110disas $T
 111cat $T.dis >> $T.aa
 112
 113# (lines of whole $T.oo) - (lines of $T.aa, i.e. "Code starting") + 3,
 114# i.e. the title + the "===..=" line (sed is counting from 1, 0 address is
 115# special)
 116faultlinenum=$(( $(wc -l $T.oo  | cut -d" " -f1) - \
 117                 $(wc -l $T.aa  | cut -d" " -f1) + 3))
 118
 119faultline=`cat $T.dis | head -1 | cut -d":" -f2-`
 120faultline=`echo "$faultline" | sed -e 's/\[/\\\[/g; s/\]/\\\]/g'`
 121
 122cat $T.oo | sed -e "${faultlinenum}s/^\(.*:\)\(.*\)/\1\*\2\t\t<-- trapping instruction/"
 123echo
 124cat $T.aa
 125cleanup
 126