Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Linux/scripts/   (Open Source Betriebssystem Version 6.17.9©)  Datei vom 24.10.2025 mit Größe 4 kB image not shown  

Quelle  decodecode   Sprache: Text

 
#!/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 ;;
 loongarch*) ARCH=loongarch ;;
    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 [ "$ARCH" = "riscv" ]; then
  OBJDUMPFLAGS="-M no-aliases --section=.text -D"
  ${CROSS_COMPILE}strip $t.o
 fi

 if [ "$ARCH" = "loongarch" ]; then
  ${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"

  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

 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

¤ Dauer der Verarbeitung: 0.27 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

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 ist noch experimentell.