#!/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
# 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"
opcode="$substr"
if [ "$ARCH" = "riscv" ]; then
opcode=$(echo $opcode | tr ' ''\n' | tac | tr -d '\n')
fi
# return if opcode bytes do not match @opline anymore
if ! echo $opline | grep -q "$opcode";
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
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.