linux-yocto/scripts/decodecode
Ivan Delalande bbeda30a6e scripts/decodecode: fix trapping instruction formatting
commit e08df079b2 upstream.

If the trapping instruction contains a ':', for a memory access through
segment registers for example, the sed substitution will insert the '*'
marker in the middle of the instruction instead of the line address:

	2b:   65 48 0f c7 0f          cmpxchg16b %gs:*(%rdi)          <-- trapping instruction

I started to think I had forgotten some quirk of the assembly syntax
before noticing that it was actually coming from the script.  Fix it to
add the address marker at the right place for these instructions:

	28:   49 8b 06                mov    (%r14),%rax
	2b:*  65 48 0f c7 0f          cmpxchg16b %gs:(%rdi)           <-- trapping instruction
	30:   0f 94 c0                sete   %al

Fixes: 18ff44b189 ("scripts/decodecode: make faulting insn ptr more robust")
Signed-off-by: Ivan Delalande <colona@arista.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Reviewed-by: Borislav Petkov <bp@suse.de>
Link: http://lkml.kernel.org/r/20200419223653.GA31248@visor
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
2020-06-04 16:28:43 -04:00

2.6 KiB
Executable File

#!/bin/sh

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

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 ;;
  3. type=4byte ;; esac

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

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

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

	${CROSS_COMPILE}strip $1.o
fi

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

	${CROSS_COMPILE}strip $1.o
fi

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

}

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

touch $T.oo if [ $marker -ne 0 ]; then 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 cat $T.dis >> $T.oo rm -f $T.o $T.s $T.dis

and fix code at-and-after marker

code=`echo "$code" | cut -c$((${marker} + 1))-`

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

(lines of whole $T.oo) - (lines of $T.aa, i.e. "Code starting") + 3,

i.e. the title + the "===..=" line (sed is counting from 1, 0 address is

special)

faultlinenum=$(( $(wc -l $T.oo | cut -d" " -f1) -
$(wc -l $T.aa | cut -d" " -f1) + 3))

faultline=cat $T.dis | head -1 | cut -d":" -f2- faultline=echo "$faultline" | sed -e 's/\[/\\\[/g; s/\]/\\\]/g'

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