
commite08df079b2
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: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2.2 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=
while read i ; do
case "$i" in Code:) code=$i ;; 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
- type=byte ;;
- type=2byte ;;
- type=4byte ;; esac
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
${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