#!/usr/bin/perl -w # ----------------------------------------------------------------------------- my $srcfile = $ARGV[0]; my @callstack = (); open (IN, "<$srcfile") || die "Cannot open $srcfile for reading: $!\n"; LINE: while () { 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 (); 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);