aboutsummaryrefslogtreecommitdiffstats
path: root/scripts/markup_oops.pl
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/markup_oops.pl')
-rw-r--r--scripts/markup_oops.pl54
1 files changed, 39 insertions, 15 deletions
diff --git a/scripts/markup_oops.pl b/scripts/markup_oops.pl
index e950f9cde019..827896f56501 100644
--- a/scripts/markup_oops.pl
+++ b/scripts/markup_oops.pl
@@ -2,6 +2,7 @@
2 2
3use File::Basename; 3use File::Basename;
4use Math::BigInt; 4use Math::BigInt;
5use Getopt::Long;
5 6
6# Copyright 2008, Intel Corporation 7# Copyright 2008, Intel Corporation
7# 8#
@@ -15,6 +16,16 @@ use Math::BigInt;
15# Arjan van de Ven <arjan@linux.intel.com> 16# Arjan van de Ven <arjan@linux.intel.com>
16 17
17 18
19my $cross_compile = "";
20my $vmlinux_name = "";
21my $modulefile = "";
22
23# Get options
24Getopt::Long::GetOptions(
25 'cross-compile|c=s' => \$cross_compile,
26 'module|m=s' => \$modulefile,
27 'help|h' => \&usage,
28) || usage ();
18my $vmlinux_name = $ARGV[0]; 29my $vmlinux_name = $ARGV[0];
19if (!defined($vmlinux_name)) { 30if (!defined($vmlinux_name)) {
20 my $kerver = `uname -r`; 31 my $kerver = `uname -r`;
@@ -23,9 +34,8 @@ if (!defined($vmlinux_name)) {
23 print "No vmlinux specified, assuming $vmlinux_name\n"; 34 print "No vmlinux specified, assuming $vmlinux_name\n";
24} 35}
25my $filename = $vmlinux_name; 36my $filename = $vmlinux_name;
26# 37
27# Step 1: Parse the oops to find the EIP value 38# Parse the oops to find the EIP value
28#
29 39
30my $target = "0"; 40my $target = "0";
31my $function; 41my $function;
@@ -177,26 +187,26 @@ my $decodestart = Math::BigInt->from_hex("0x$target") - Math::BigInt->from_hex("
177my $decodestop = Math::BigInt->from_hex("0x$target") + 8192; 187my $decodestop = Math::BigInt->from_hex("0x$target") + 8192;
178if ($target eq "0") { 188if ($target eq "0") {
179 print "No oops found!\n"; 189 print "No oops found!\n";
180 print "Usage: \n"; 190 usage();
181 print " dmesg | perl scripts/markup_oops.pl vmlinux\n";
182 exit;
183} 191}
184 192
185# if it's a module, we need to find the .ko file and calculate a load offset 193# if it's a module, we need to find the .ko file and calculate a load offset
186if ($module ne "") { 194if ($module ne "") {
187 my $modulefile = `modinfo $module | grep '^filename:' | awk '{ print \$2 }'`; 195 if ($modulefile eq "") {
188 chomp($modulefile); 196 $modulefile = `modinfo -F filename $module`;
197 chomp($modulefile);
198 }
189 $filename = $modulefile; 199 $filename = $modulefile;
190 if ($filename eq "") { 200 if ($filename eq "") {
191 print "Module .ko file for $module not found. Aborting\n"; 201 print "Module .ko file for $module not found. Aborting\n";
192 exit; 202 exit;
193 } 203 }
194 # ok so we found the module, now we need to calculate the vma offset 204 # ok so we found the module, now we need to calculate the vma offset
195 open(FILE, "objdump -dS $filename |") || die "Cannot start objdump"; 205 open(FILE, $cross_compile."objdump -dS $filename |") || die "Cannot start objdump";
196 while (<FILE>) { 206 while (<FILE>) {
197 if ($_ =~ /^([0-9a-f]+) \<$function\>\:/) { 207 if ($_ =~ /^([0-9a-f]+) \<$function\>\:/) {
198 my $fu = $1; 208 my $fu = $1;
199 $vmaoffset = hex($target) - hex($fu) - hex($func_offset); 209 $vmaoffset = Math::BigInt->from_hex("0x$target") - Math::BigInt->from_hex("0x$fu") - Math::BigInt->from_hex("0x$func_offset");
200 } 210 }
201 } 211 }
202 close(FILE); 212 close(FILE);
@@ -204,7 +214,7 @@ if ($module ne "") {
204 214
205my $counter = 0; 215my $counter = 0;
206my $state = 0; 216my $state = 0;
207my $center = 0; 217my $center = -1;
208my @lines; 218my @lines;
209my @reglines; 219my @reglines;
210 220
@@ -212,7 +222,7 @@ sub InRange {
212 my ($address, $target) = @_; 222 my ($address, $target) = @_;
213 my $ad = "0x".$address; 223 my $ad = "0x".$address;
214 my $ta = "0x".$target; 224 my $ta = "0x".$target;
215 my $delta = hex($ad) - hex($ta); 225 my $delta = Math::BigInt->from_hex($ad) - Math::BigInt->from_hex($ta);
216 226
217 if (($delta > -4096) && ($delta < 4096)) { 227 if (($delta > -4096) && ($delta < 4096)) {
218 return 1; 228 return 1;
@@ -225,7 +235,7 @@ sub InRange {
225# first, parse the input into the lines array, but to keep size down, 235# first, parse the input into the lines array, but to keep size down,
226# we only do this for 4Kb around the sweet spot 236# we only do this for 4Kb around the sweet spot
227 237
228open(FILE, "objdump -dS --adjust-vma=$vmaoffset --start-address=$decodestart --stop-address=$decodestop $filename |") || die "Cannot start objdump"; 238open(FILE, $cross_compile."objdump -dS --adjust-vma=$vmaoffset --start-address=$decodestart --stop-address=$decodestop $filename |") || die "Cannot start objdump";
229 239
230while (<FILE>) { 240while (<FILE>) {
231 my $line = $_; 241 my $line = $_;
@@ -236,7 +246,8 @@ while (<FILE>) {
236 $state = 1; 246 $state = 1;
237 } 247 }
238 } 248 }
239 } else { 249 }
250 if ($state == 1) {
240 if ($line =~ /^([a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9]+)\:/) { 251 if ($line =~ /^([a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9]+)\:/) {
241 my $val = $1; 252 my $val = $1;
242 if (!InRange($val, $target)) { 253 if (!InRange($val, $target)) {
@@ -259,7 +270,7 @@ if ($counter == 0) {
259 exit; 270 exit;
260} 271}
261 272
262if ($center == 0) { 273if ($center == -1) {
263 print "No matching code found \n"; 274 print "No matching code found \n";
264 exit; 275 exit;
265} 276}
@@ -344,3 +355,16 @@ while ($i < $finish) {
344 $i = $i +1; 355 $i = $i +1;
345} 356}
346 357
358sub usage {
359 print <<EOT;
360Usage:
361 dmesg | perl $0 [OPTION] [VMLINUX]
362
363OPTION:
364 -c, --cross-compile CROSS_COMPILE Specify the prefix used for toolchain.
365 -m, --module MODULE_DIRNAME Specify the module filename.
366 -h, --help Help.
367EOT
368 exit;
369}
370