mirror of
https://github.com/ctm/executor.git
synced 2024-11-30 05:51:22 +00:00
101 lines
1.8 KiB
Perl
Executable File
101 lines
1.8 KiB
Perl
Executable File
#!/usr/bin/perl -w
|
|
|
|
die "Usage: $0 nm_-n_output_file traceback_file\n"
|
|
if ($#ARGV != 1);
|
|
|
|
print STDERR "Parsing nm file...";
|
|
|
|
&read_nm_file ($ARGV[0]);
|
|
|
|
print STDERR "done.\n";
|
|
|
|
&process_traceback ($ARGV[1]);
|
|
|
|
|
|
sub read_nm_file {
|
|
local ($file) = @_;
|
|
|
|
open (NM_FILE, "< $file") || die "Unable to open $file: $!\n";
|
|
|
|
$last_addr = 0;
|
|
|
|
while (<NM_FILE>)
|
|
{
|
|
if (($addr, $label) = /([0-9a-fA-F]+)\s+\w+\s+([^L\.]\w*)\s*$/)
|
|
{
|
|
if ($label ne '___gnu_compiled_c')
|
|
{
|
|
$new_addr = hex ($addr);
|
|
die "fatal error: nm file isn't sorted!\n"
|
|
if ($new_addr < $last_addr);
|
|
$last_addr = $new_addr;
|
|
|
|
push (@known_labels, $new_addr);
|
|
push (@known_labels, $label);
|
|
}
|
|
}
|
|
}
|
|
|
|
# Put known sentinels at the end
|
|
push (@known_labels, hex ("100000000"));
|
|
push (@known_labels, '<UNKNOWN>');
|
|
push (@known_labels, hex ("100000001"));
|
|
push (@known_labels, '<UNKNOWN>');
|
|
|
|
close (NM_FILE);
|
|
}
|
|
|
|
|
|
sub process_traceback
|
|
{
|
|
local ($file) = @_;
|
|
local ($line);
|
|
|
|
open (TRACEBACK, "< $file") || die "Unable to open $file: $!\n";
|
|
|
|
while (!eof (TRACEBACK))
|
|
{
|
|
# Skip any leading junk
|
|
while (<TRACEBACK>)
|
|
{
|
|
s/\r//g;
|
|
$line = $_;
|
|
print $line;
|
|
last if ($line =~ /at eip=/i);
|
|
}
|
|
|
|
# Cruise through the register dumps
|
|
while (<TRACEBACK>)
|
|
{
|
|
s/\r//g;
|
|
print;
|
|
last if (/frame/i);
|
|
}
|
|
|
|
# Now process the traceback
|
|
while (<TRACEBACK>)
|
|
{
|
|
s/\r//g;
|
|
$line = $_;
|
|
if (!(($addr_string) = /\s*0x([0-9a-fA-F]+)\s*$/))
|
|
{
|
|
print $line;
|
|
last;
|
|
}
|
|
$addr = hex ($addr_string);
|
|
|
|
for ($i = 2; $i <= $#known_labels; $i += 2)
|
|
{
|
|
if ($known_labels[$i] > $addr)
|
|
{
|
|
print (" 0x$addr_string\t$known_labels[$i - 1]");
|
|
printf (" + 0x%x\n", $addr - $known_labels[$i - 2]);
|
|
last;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
close (TRACEBACK);
|
|
}
|