#!/bin/bash
# SPDX-License-Identifier: GPL-2.0
# Disassemble the Code: line in Linux oopses
# usage: decodecode < oops.file
#
# options: set env. variable AFLAGS=options to pass options to "as";
# e.g., to decode an i386 oops on an x86_64 system, use:
# AFLAGS=--32 decodecode < 386.oops
# PC=hex - the PC (program counter) the oops points to

faultlinenum=1

cleanup() {
	rm -f $T $T.s $T.o $T.oo $T.aa $T.dis
	exit 1
}

die() {
	echo "$@"
	exit 1
}

trap cleanup EXIT

T=`mktemp` || die "cannot create temp file"
code=
cont=

while read i ; do

case "$i" in
*Code:*)
	code=$i
	cont=yes
	;;
*)
	[ -n "$cont" ] && {
		xdump="$(echo $i | grep '^[[:xdigit:]<>[:space:]]\+$')"
		if [ -n "$xdump" ]; then
			code="$code $xdump"
		else
			cont=
		fi
	}
	;;
esac

done

if [ -z "$code" ]; then
	rm $T
	exit
fi

echo $code
code=`echo $code | sed -e 's/.*Code: //'`

width=`expr index "$code" ' '`
width=$((($width-1)/2))
case $width in
1) type=byte ;;
2) type=2byte ;;
4) type=4byte ;;
esac

if [ -z "$ARCH" ]; then
    case `uname -m` in
	aarch64*) ARCH=arm64 ;;
	arm*) ARCH=arm ;;
    esac
fi

# Params: (tmp_file, pc_sub)
disas() {
	t=$1
	pc_sub=$2

	${CROSS_COMPILE}as $AFLAGS -o $t.o $t.s > /dev/null 2>&1

	if [ "$ARCH" = "arm" ]; then
		if [ $width -eq 2 ]; then
			OBJDUMPFLAGS="-M force-thumb"
		fi

		${CROSS_COMPILE}strip $t.o
	fi

	if [ "$ARCH" = "arm64" ]; then
		if [ $width -eq 4 ]; then
			type=inst
		fi

		${CROSS_COMPILE}strip $t.o
	fi

	if [ $pc_sub -ne 0 ]; then
		if [ $PC ]; then
			adj_vma=$(( $PC - $pc_sub ))
			OBJDUMPFLAGS="$OBJDUMPFLAGS --adjust-vma=$adj_vma"
		fi
	fi

	${CROSS_COMPILE}objdump $OBJDUMPFLAGS -S $t.o | \
		grep -v "/tmp\|Disassembly\|\.text\|^$" > $t.dis 2>&1
}

# Match the maximum number of opcode bytes from @op_bytes contained within
# @opline
#
# Params:
# @op_bytes: The string of bytes from the Code: line
# @opline: The disassembled line coming from objdump
#
# Returns:
# The max number of opcode bytes from the beginning of @op_bytes which match
# the opcode bytes in the objdump line.
get_substr_opcode_bytes_num()
{
	local op_bytes=$1
	local opline=$2

	local retval=0
	substr=""

	for opc in $op_bytes;
	do
		substr+="$opc"

		# return if opcode bytes do not match @opline anymore
		if ! echo $opline | grep -q "$substr";
		then
			break
		fi

		# add trailing space
		substr+=" "
		retval=$((retval+1))
	done

	return $retval
}

# Return the line number in objdump output to where the IP marker in the Code:
# line points to
#
# Params:
# @all_code: code in bytes without the marker
# @dis_file: disassembled file
# @ip_byte: The byte to which the IP points to
get_faultlinenum()
{
	local all_code="$1"
	local dis_file="$2"

	# num bytes including IP byte
	local num_bytes_ip=$(( $3 + 1 * $width ))

	# Add the two header lines (we're counting from 1).
	local retval=3

	# remove marker
	all_code=$(echo $all_code | sed -e 's/[<>()]//g')

	while read line
	do
		get_substr_opcode_bytes_num "$all_code" "$line"
		ate_opcodes=$?

		if ! (( $ate_opcodes )); then
			continue
		fi

		num_bytes_ip=$((num_bytes_ip - ($ate_opcodes * $width) ))
		if (( $num_bytes_ip <= 0 )); then
			break
		fi

		# Delete matched opcode bytes from all_code. For that, compute
		# how many chars those opcodes are represented by and include
		# trailing space.
		#
		# a byte is 2 chars, ate_opcodes is also the number of trailing
		# spaces
		del_chars=$(( ($ate_opcodes * $width * 2) + $ate_opcodes ))

		all_code=$(echo $all_code | sed -e "s!^.\{$del_chars\}!!")

		let "retval+=1"

	done < $dis_file

	return $retval
}

marker=`expr index "$code" "\<"`
if [ $marker -eq 0 ]; then
	marker=`expr index "$code" "\("`
fi

touch $T.oo
if [ $marker -ne 0 ]; then
	# How many bytes to subtract from the program counter
	# in order to get to the beginning virtual address of the
	# Code:
	pc_sub=$(( (($marker - 1) / (2 * $width + 1)) * $width ))
	echo All code >> $T.oo
	echo ======== >> $T.oo
	beforemark=`echo "$code"`
	echo -n "	.$type 0x" > $T.s

	echo $beforemark | sed -e 's/ /,0x/g; s/[<>()]//g' >> $T.s

	disas $T $pc_sub

	cat $T.dis >> $T.oo

	get_faultlinenum "$code" "$T.dis" $pc_sub
	faultlinenum=$?

	# and fix code at-and-after marker
	code=`echo "$code" | cut -c$((${marker} + 1))-`

	rm -f $T.o $T.s $T.dis
fi

echo Code starting with the faulting instruction  > $T.aa
echo =========================================== >> $T.aa
code=`echo $code | sed -e 's/\r//;s/ [<(]/ /;s/[>)] / /;s/ /,0x/g; s/[>)]$//'`
echo -n "	.$type 0x" > $T.s
echo $code >> $T.s
disas $T 0
cat $T.dis >> $T.aa

cat $T.oo | sed -e "${faultlinenum}s/^\([^:]*:\)\(.*\)/\1\*\2\t\t<-- trapping instruction/"
echo
cat $T.aa
cleanup
