1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
|
#!/usr/bin/perl -w
#
# A perl script which compares the given System.map file with
# the /proc/ksym table (to see if it the given System.map file
# corresponds to the running kernel).
if( $#ARGV != 0 ) {
print "usage: symchecker.pl System.map\n";
exit 1;
}
if( ! -f $ARGV[0] ) {
print "The file '$ARGV[0]' could not be found\n";
exit 1;
}
#print "**** Examining '".$ARGV[0]."' ****\n";
$a = `cat $ARGV[0] | awk -- '{ print \$3 ":" \$1 }'`;
%A = split(/[:\n]/, $a);
$b = `cat /proc/ksyms`;
# We must handle three formats:
#
# 'c0041bb4 getname'
# 'c0041bb4 getname_R7c60d66e'
# 'c0031234 sk_run_filter_R__ver_sk_run_filter'
#
$b =~ s/_R[a-f0-9]*\n/\n/g;
$b =~ s/_R__.*\n/\n/g;
@B = $b =~ /([a-fA-F0-9]*) (.*)/g;
$miscount=0;
$errcount=0;
for( $i=0 ; $i <= $#B; $i=$i+2 ){
if( $B[$i+1] =~ /\[/g ) {
next;
}
if( !defined($A{$B[$i+1]}) ) {
#print "Warning - the symbol '".$B[$i+1]."' is undefined\n";
$miscount++;
if( $miscount > 14 ) {
print "Too many missing symbols! Probably a bad symbol file.\n";
exit 1;
}
# the _R[hex] strip above could cause a few missing symbols
next;
}
if( hex $A{$B[$i+1]} != hex $B[$i] ) {
# some symbols are defined twice... check once more
if( $a =~ /$B[$i+1].*$B[$i]/ ) {
next;
}
if( $errcount == 0 ) {
print("Discrepancy found - does not correspond to the running kernel:\n");
}
print " ".$B[$i]." ".$B[$i+1]." (".$A{$B[$i+1]}.")\n";
if( $errcount >= 2 ) {
exit 1;
}
$errcount++;
}
}
if( $errcount > 0 ) {
exit 1;
}
print "**** Symbol file matches ****\n";
exit 0;
|