1642f114ce
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>
133 lines
2.6 KiB
Bash
Executable File
133 lines
2.6 KiB
Bash
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 ;;
|
|
4) 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
|