Annotation of qemu/roms/ipxe/src/util/symcheck.pl, revision 1.1.1.1

1.1       root        1: #!/usr/bin/perl -w
                      2: 
                      3: use strict;
                      4: use warnings;
                      5: 
                      6: use constant WARNING_SIZE => 512;
                      7: 
                      8: my $symtab = {};
                      9: 
                     10: # Scan output of "objdump -w -t bin/blib.a" and build up symbol table
                     11: #
                     12: my $object;
                     13: while ( <> ) {
                     14:   chomp;
                     15:   if ( /^In archive/ ) {
                     16:     # Do nothing
                     17:   } elsif ( /^$/ ) {
                     18:     # Do nothing
                     19:   } elsif ( /^(\S+\.o):\s+file format/ ) {
                     20:     $object = $1;
                     21:   } elsif ( /^SYMBOL TABLE:/ ) {
                     22:     # Do nothing
                     23:   } elsif ( /^([0-9a-fA-F]+)\s(l|g|\s)......\s(\S+)\s+([0-9a-fA-F]+)\s+(\S+)$/ ) {
                     24:     my $value = $1;
                     25:     my $scope = $2;
                     26:     my $section = $3;
                     27:     my $size = $4;
                     28:     my $symbol = $5;
                     29:     $symtab->{$object}->{$symbol} = {
                     30:       global   => ( $scope ne "l" ),
                     31:       section  => ( $section eq "*UND*" ? undef : $section ),
                     32:       value    => ( $value ? hex ( $value ) : 0 ),
                     33:       size     => ( $size ? hex ( $size ) : 0 ),
                     34:     };
                     35:   } else {
                     36:     die "Unrecognized line \"$_\"";
                     37:   }
                     38: }
                     39: 
                     40: # Add symbols that we know will be generated or required by the linker
                     41: #
                     42: foreach my $object ( keys %$symtab ) {
                     43:   my $obj_symbol = "obj_$object";
                     44:   $obj_symbol =~ s/\.o$//;
                     45:   $obj_symbol =~ s/\W/_/g;
                     46:   $symtab->{LINKER}->{$obj_symbol} = {
                     47:     global     => 1,
                     48:     section    => undef,
                     49:     value      => 0,
                     50:     size       => 0,
                     51:   };
                     52: }
                     53: foreach my $link_sym qw ( __prefix _prefix _prefix_load_offset
                     54:                          _prefix_size _prefix_progbits_size _prefix_size_pgh
                     55:                          __text16 _text16 _text16_load_offset
                     56:                          _text16_size _text16_progbits_size _text16_size_pgh
                     57:                          __data16 _data16 _data16_load_offset
                     58:                          _data16_size _data16_progbits_size _data16_size_pgh
                     59:                          __text _text __data _data _textdata_load_offset
                     60:                          _textdata_size _textdata_progbits_size
                     61:                          __rodata __bss _end
                     62:                          _payload_offset _max_align
                     63:                          _load_size _load_size_pgh _load_size_sect
                     64:                          pci_vendor_id pci_device_id ) {
                     65:   $symtab->{LINKER}->{$link_sym} = {
                     66:     global     => 1,
                     67:     section    => '*ABS*',
                     68:     value      => 0,
                     69:     size       => 0,
                     70:   };
                     71: }
                     72: 
                     73: # Add symbols that we know will be used by the debug system
                     74: #
                     75: foreach my $debug_sym qw ( dbg_autocolourise dbg_decolourise
                     76:                           dbg_hex_dump_da ) {
                     77:   $symtab->{DEBUG}->{$debug_sym} = {
                     78:     global     => 1,
                     79:     section    => undef,
                     80:     value      => 0,
                     81:     size       => 0,
                     82:   };
                     83: }
                     84: 
                     85: # Build up requires, provides and shares symbol tables for global
                     86: # symbols
                     87: #
                     88: my $globals = {};
                     89: while ( ( my $object, my $symbols ) = each %$symtab ) {
                     90:   while ( ( my $symbol, my $info ) = each %$symbols ) {
                     91:     if ( $info->{global} ) {
                     92:       my $category;
                     93:       if ( ! defined $info->{section} ) {
                     94:        $category = "requires";
                     95:       } elsif ( $info->{section} eq "*COM*" ) {
                     96:        $category = "shares";
                     97:       } else {
                     98:        $category = "provides";
                     99:       }
                    100:       $globals->{$symbol}->{$category}->{$object} = 1;
                    101:     }
                    102:   }
                    103: }
                    104: 
                    105: # Check for multiply defined, never-defined and unused global symbols
                    106: #
                    107: my $problems = {};
                    108: while ( ( my $symbol, my $info ) = each %$globals ) {
                    109:   my @provides = keys %{$info->{provides}};
                    110:   my @requires = keys %{$info->{requires}};
                    111:   my @shares = keys %{$info->{shares}};
                    112: 
                    113:   if ( ( @provides == 0 ) && ( @shares == 1 ) ) {
                    114:     # A symbol "shared" by just a single file is actually being
                    115:     # provided by that file; it just doesn't have an initialiser.
                    116:     @provides = @shares;
                    117:     @shares = ();
                    118:   }
                    119: 
                    120:   if ( ( @requires > 0 ) && ( @provides == 0 ) && ( @shares == 0 ) ) {
                    121:     # No object provides this symbol, but some objects require it.
                    122:     $problems->{$_}->{nonexistent}->{$symbol} = 1 foreach @requires;
                    123:   }
                    124: 
                    125:   if ( ( @requires == 0 ) && ( @provides > 0 ) ) {
                    126:     # No object requires this symbol, but some objects provide it.
                    127:     foreach my $provide ( @provides ) {
                    128:       if ( $provide eq "LINKER" ) {
                    129:        # Linker-provided symbols are exempt from this check.
                    130:       } elsif ( $symtab->{$provide}->{$symbol}->{section} =~ /^\.tbl\./ ) {
                    131:        # Linker tables are exempt from this check.
                    132:       } else {
                    133:        $problems->{$provide}->{unused}->{$symbol} = 1;
                    134:       }
                    135:     }
                    136:   }
                    137: 
                    138:   if ( ( @shares > 0 ) && ( @provides > 0 ) ) {
                    139:     # A shared symbol is being initialised by an object
                    140:     $problems->{$_}->{shared}->{$symbol} = 1 foreach @provides;
                    141:   }
                    142: 
                    143:   if ( @provides > 1 ) {
                    144:     # A non-shared symbol is defined in multiple objects
                    145:     $problems->{$_}->{multiples}->{$symbol} = 1 foreach @provides;
                    146:   }
                    147: }
                    148: 
                    149: # Check for excessively large local symbols.  Text and rodata symbols
                    150: # are exempt from this check
                    151: #
                    152: while ( ( my $object, my $symbols ) = each %$symtab ) {
                    153:   while ( ( my $symbol, my $info ) = each %$symbols ) {
                    154:     if ( ( ! $info->{global} ) &&
                    155:         ( ( defined $info->{section} ) &&
                    156:           ! ( $info->{section} =~ /^(\.text|\.rodata)/ ) ) &&
                    157:         ( $info->{size} >= WARNING_SIZE ) ) {
                    158:       $problems->{$object}->{large}->{$symbol} = 1;
                    159:     }
                    160:   }
                    161: }
                    162: 
                    163: # Print out error messages
                    164: #
                    165: my $errors = 0;
                    166: my $warnings = 0;
                    167: foreach my $object ( sort keys %$problems ) {
                    168:   my @nonexistent = sort keys %{$problems->{$object}->{nonexistent}};
                    169:   my @multiples = sort keys %{$problems->{$object}->{multiples}};
                    170:   my @unused = sort keys %{$problems->{$object}->{unused}};
                    171:   my @shared = sort keys %{$problems->{$object}->{shared}};
                    172:   my @large = sort keys %{$problems->{$object}->{large}};
                    173: 
                    174:   print "WARN $object provides unused symbol $_\n" foreach @unused;
                    175:   $warnings += @unused;
                    176:   print "WARN $object has large static symbol $_\n" foreach @large;
                    177:   $warnings += @large;
                    178:   print "ERR  $object requires non-existent symbol $_\n" foreach @nonexistent;
                    179:   $errors += @nonexistent;
                    180:   foreach my $symbol ( @multiples ) {
                    181:     my @other_objects = sort grep { $_ ne $object }
                    182:                        keys %{$globals->{$symbol}->{provides}};
                    183:     print "ERR  $object provides symbol $symbol"
                    184:        ." (also provided by @other_objects)\n";
                    185:   }
                    186:   $errors += @multiples;
                    187:   print "ERR  $object misuses shared symbol $_\n" foreach @shared;
                    188: }
                    189: 
                    190: print "$errors error(s), $warnings warning(s)\n";
                    191: exit ( $errors ? 1 : 0 );

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.