blob: 6030f08e4bf8119251afef93e4b9a9b2f5f7cafe [file] [log] [blame]
#!/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);