From 0139f1d9539395ca341e17060ae26f44f5f31434 Mon Sep 17 00:00:00 2001 From: Hui Zhu Date: Thu, 28 Jan 2010 06:58:02 +0000 Subject: markup_oops.pl: fix for faulting instruction in the first line of a range I got a "No matching code found" when I use markup_oops.pl parse a error in a x86_64 module. cat e.c int init_module(void) { char *buf = 0; buf[0] = 3; return 0; } void cleanup_module(void) { //char *buf = 0; //buf[0] = 3; } MODULE_AUTHOR("Hui Zhu"); MODULE_LICENSE("GPL"); 0000000000000000 : init_module(): /home/teawater/study/kernel/stack2core/example/e.c:10 0: c6 04 25 00 00 00 00 movb $0x3,0x0 7: 03 /home/teawater/study/kernel/stack2core/example/e.c:13 8: 31 c0 xor %eax,%eax a: c3 retq b: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1) 0000000000000010 : cleanup_module(): /home/teawater/study/kernel/stack2core/example/e.c:20 10: f3 c3 repz retq 12: 90 nop 13: 90 nop Disassembly of section .modinfo: This is because the faulting instruction "movb $0x3,0x0" is the first line of the range. In the markup_oops.pl: main::(./scripts/markup_oops.pl:245): 245: if (InRange($1, $target)) { DB<2> p $line ffffffffa001b000: c6 04 25 00 00 00 00 movb $0x3,0x0 DB<3> p $counter 0 It just set $center in next loop. So it cannot get the $center. And even if $center is set to the right value 0. if ($center == 0) { print "No matching code found \n"; exit; } The first line $center will be 0, so I change the default value to -1. Signed-off-by: Hui Zhu Signed-off-by: Michal Marek --- scripts/markup_oops.pl | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'scripts/markup_oops.pl') diff --git a/scripts/markup_oops.pl b/scripts/markup_oops.pl index ce3e40b01e48..4a95539c807a 100644 --- a/scripts/markup_oops.pl +++ b/scripts/markup_oops.pl @@ -204,7 +204,7 @@ if ($module ne "") { my $counter = 0; my $state = 0; -my $center = 0; +my $center = -1; my @lines; my @reglines; @@ -236,7 +236,8 @@ while () { $state = 1; } } - } else { + } + if ($state == 1) { if ($line =~ /^([a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9]+)\:/) { my $val = $1; if (!InRange($val, $target)) { @@ -259,7 +260,7 @@ if ($counter == 0) { exit; } -if ($center == 0) { +if ($center == -1) { print "No matching code found \n"; exit; } -- cgit v1.2.3 From 52e13e219d5930fb8fb774050e6ecffa244a60a9 Mon Sep 17 00:00:00 2001 From: Hui Zhu Date: Tue, 26 Jan 2010 17:13:07 +0800 Subject: markup_oops.pl: add options to improve cross-sompilation environments The markup_oops.pl have 3 troubles to support cross-compiler environment: 1. It use objdump directly. 2. It use modinfo to get the message of module. 3. It use hex function that cannot support 64-bit number in 32-bit arch. This patch add 3 options to markup_oops.pl: 1. -c CROSS_COMPILE Specify the prefix used for toolchain. 2. -m MODULE_DIRNAME Specify the module directory name. 3. Change hex function to Math::BigInt->from_hex. After this patch, parse the x8664 oops in x86, we can: cat amd64m | perl ~/kernel/tmp/m.pl -c /home/teawater/kernel/bin/x8664- -m ./e.ko vmlinux Thanks, Hui Signed-off-by: Hui Zhu Cc: Andrew Morton Cc: Arjan van de Ven Cc: Sam Ravnborg Cc: ozan@pardus.org.tr Cc: Matthew Wilcox Acked-by: WANG Cong Signed-off-by: Michal Marek --- scripts/markup_oops.pl | 49 ++++++++++++++++++++++++++++++++++++------------- 1 file changed, 36 insertions(+), 13 deletions(-) (limited to 'scripts/markup_oops.pl') diff --git a/scripts/markup_oops.pl b/scripts/markup_oops.pl index 4a95539c807a..a7e8e019e03d 100644 --- a/scripts/markup_oops.pl +++ b/scripts/markup_oops.pl @@ -2,6 +2,7 @@ use File::Basename; use Math::BigInt; +use Getopt::Long; # Copyright 2008, Intel Corporation # @@ -15,7 +16,17 @@ use Math::BigInt; # Arjan van de Ven -my $vmlinux_name = $ARGV[0]; +my $cross_compile = ""; +my $vmlinux_name = ""; +my $modulefile = ""; + +# Get options +Getopt::Long::GetOptions( + 'cross-compile|c=s' => \$cross_compile, + 'module|m=s' => \$modulefile, + 'help|h' => \&usage, +); +my $vmlinux_name = $ARGV[$#ARGV]; if (!defined($vmlinux_name)) { my $kerver = `uname -r`; chomp($kerver); @@ -23,9 +34,8 @@ if (!defined($vmlinux_name)) { print "No vmlinux specified, assuming $vmlinux_name\n"; } my $filename = $vmlinux_name; -# -# Step 1: Parse the oops to find the EIP value -# + +# Parse the oops to find the EIP value my $target = "0"; my $function; @@ -177,26 +187,26 @@ my $decodestart = Math::BigInt->from_hex("0x$target") - Math::BigInt->from_hex(" my $decodestop = Math::BigInt->from_hex("0x$target") + 8192; if ($target eq "0") { print "No oops found!\n"; - print "Usage: \n"; - print " dmesg | perl scripts/markup_oops.pl vmlinux\n"; - exit; + usage(); } # if it's a module, we need to find the .ko file and calculate a load offset if ($module ne "") { - my $modulefile = `modinfo $module | grep '^filename:' | awk '{ print \$2 }'`; - chomp($modulefile); + if ($modulefile eq "") { + my $modulefile = `modinfo $module | grep '^filename:' | awk '{ print \$2 }'`; + chomp($modulefile); + } $filename = $modulefile; if ($filename eq "") { print "Module .ko file for $module not found. Aborting\n"; exit; } # ok so we found the module, now we need to calculate the vma offset - open(FILE, "objdump -dS $filename |") || die "Cannot start objdump"; + open(FILE, $cross_compile."objdump -dS $filename |") || die "Cannot start objdump"; while () { if ($_ =~ /^([0-9a-f]+) \<$function\>\:/) { my $fu = $1; - $vmaoffset = hex($target) - hex($fu) - hex($func_offset); + $vmaoffset = Math::BigInt->from_hex("0x$target") - Math::BigInt->from_hex("0x$fu") - Math::BigInt->from_hex("0x$func_offset"); } } close(FILE); @@ -212,7 +222,7 @@ sub InRange { my ($address, $target) = @_; my $ad = "0x".$address; my $ta = "0x".$target; - my $delta = hex($ad) - hex($ta); + my $delta = Math::BigInt->from_hex($ad) - Math::BigInt->from_hex($ta); if (($delta > -4096) && ($delta < 4096)) { return 1; @@ -225,7 +235,7 @@ sub InRange { # first, parse the input into the lines array, but to keep size down, # we only do this for 4Kb around the sweet spot -open(FILE, "objdump -dS --adjust-vma=$vmaoffset --start-address=$decodestart --stop-address=$decodestop $filename |") || die "Cannot start objdump"; +open(FILE, $cross_compile."objdump -dS --adjust-vma=$vmaoffset --start-address=$decodestart --stop-address=$decodestop $filename |") || die "Cannot start objdump"; while () { my $line = $_; @@ -345,3 +355,16 @@ while ($i < $finish) { $i = $i +1; } +sub usage { + print < Date: Mon, 1 Feb 2010 13:41:22 +0800 Subject: markup_oops.pl: minor fixes 1. Fix a little format issue. 2. Check the return of "Getopt::Long::GetOptions". Output usage and exit if it get error. 3. Change $ARGV[$#ARGV] to $ARGV[0]. 4. Change the code which get $modulefile from modinfo. Replace the pipeline with `modinfo -F filename $module`. 4. Change usage from "Specify the module directory name" to "Specify the module filename". Signed-off-by: Hui Zhu Signed-off-by: Michal Marek --- scripts/markup_oops.pl | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'scripts/markup_oops.pl') diff --git a/scripts/markup_oops.pl b/scripts/markup_oops.pl index a7e8e019e03d..90e1d9aa35b5 100644 --- a/scripts/markup_oops.pl +++ b/scripts/markup_oops.pl @@ -23,10 +23,10 @@ my $modulefile = ""; # Get options Getopt::Long::GetOptions( 'cross-compile|c=s' => \$cross_compile, - 'module|m=s' => \$modulefile, + 'module|m=s' => \$modulefile, 'help|h' => \&usage, -); -my $vmlinux_name = $ARGV[$#ARGV]; +) || usage (); +my $vmlinux_name = $ARGV[0]; if (!defined($vmlinux_name)) { my $kerver = `uname -r`; chomp($kerver); @@ -193,7 +193,7 @@ if ($target eq "0") { # if it's a module, we need to find the .ko file and calculate a load offset if ($module ne "") { if ($modulefile eq "") { - my $modulefile = `modinfo $module | grep '^filename:' | awk '{ print \$2 }'`; + $modulefile = `modinfo -F filename $module`; chomp($modulefile); } $filename = $modulefile; @@ -362,7 +362,7 @@ Usage: OPTION: -c, --cross-compile CROSS_COMPILE Specify the prefix used for toolchain. - -m, --module MODULE_DIRNAME Specify the module directory name. + -m, --module MODULE_DIRNAME Specify the module filename. -h, --help Help. EOT exit; -- cgit v1.2.3