62 lines
1.4 KiB
Plaintext
62 lines
1.4 KiB
Plaintext
|
#!/usr/bin/perl -w
|
||
|
# -----------------------------------------------------------------------------
|
||
|
|
||
|
my $srcfile = $ARGV[0];
|
||
|
my @callstack = ();
|
||
|
|
||
|
open (IN, "<$srcfile") || die "Cannot open $srcfile for reading: $!\n";
|
||
|
LINE:
|
||
|
while (<IN>) {
|
||
|
if (/^Call ([A-Za-z0-9]+\.[0-9]+): .*\)/) {
|
||
|
my $func = $1;
|
||
|
if (/ ret=(........)$/ ||
|
||
|
/ ret=(....:....) ds=....$/) {
|
||
|
my $retaddr = $1;
|
||
|
push @callstack, [$func,$retaddr];
|
||
|
next;
|
||
|
} else {
|
||
|
# Assume a line got cut by a line feed in a string.
|
||
|
$_ .= scalar (<IN>);
|
||
|
print "[$_]";
|
||
|
redo;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
if (/^Ret ([A-Za-z0-9]+\.[0-9]+): .* ret=(........)$/ ||
|
||
|
/^Ret ([A-Za-z0-9]+\.[0-9]+): .* ret=(....:....) ds=....$/) {
|
||
|
my $func = $1;
|
||
|
my $retaddr = $2;
|
||
|
my ($topfunc,$topaddr);
|
||
|
|
||
|
POP:
|
||
|
while (1) {
|
||
|
if ($#callstack == -1) {
|
||
|
print "Error: Return from $func to $retaddr with empty stack.\n";
|
||
|
next LINE;
|
||
|
}
|
||
|
|
||
|
($topfunc,$topaddr) = @{pop @callstack};
|
||
|
|
||
|
if ($topfunc ne $func) {
|
||
|
print "Error: Return from $topfunc, but call from $func.\n";
|
||
|
next POP
|
||
|
}
|
||
|
last POP;
|
||
|
}
|
||
|
|
||
|
if ($topaddr eq $retaddr) {
|
||
|
print "OK: $func from $retaddr.\n";
|
||
|
} else {
|
||
|
print "Error: Return from $func is to $retaddr, not $topaddr.\n";
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
while ($#callstack != -1) {
|
||
|
my ($topfunc,$topaddr) = @{pop @callstack};
|
||
|
print "Error: leftover call to $topfunc from $topaddr.\n";
|
||
|
}
|
||
|
|
||
|
close (IN);
|