3 # we use BigInts for handling 64-bit values on IA32 systems
11 my $sym_objdump = 'nm -nC';
12 my $dis_objdump = 'objdump -drlC';
13 my $hdr_objdump = 'objdump -h';
14 my $start_symbol = '_initcall_start';
15 my $end_symbol = '_initcall_end';
16 my $kernel = 'fiasco.image';
20 my @ignore_funcs = ();
22 my $opt = { "kernel" => \$kernel,
23 "start-symbol" => \$start_symbol,
24 "end-symbol" => \$end_symbol,
26 "ignore-function" => \@ignore_funcs,
27 "target" => \$target };
29 Getopt::Long::Configure ('bundling','no_ignore_case','auto_abbrev');
44 my @gr = grep /$opt/, @Wswitch;
45 # print "W: ".join(" ",@gr)."\n";
49 $dis_objdump = $target.$dis_objdump;
50 $hdr_objdump = $target.$hdr_objdump;
51 $sym_objdump = $target.$sym_objdump;
53 $werror = 1 if have_warn_opt("error");
54 if (!have_warn_opt("static-construction")) {
55 push @ignore_funcs, ("(_Z41)?__static_initialization_and_destruction_0(ii\\.(clone|part)\\.\\d+)?");
56 push @ignore_funcs, ("_GLOBAL__(sub_)?I\\.\\S*");
57 push @ignore_funcs, ("_GLOBAL__sub_I__Z\\S*");
58 push @ignore_funcs, ("global constructors keyed to \\S*");
59 push @ignore_funcs, ("T\\.\\d+");
62 my $ignore_funcs = join("|",@ignore_funcs);
64 #print "Ignore: $ignore_funcs\n";
66 my @symbols = split($/,qx{$sym_objdump $kernel});
68 my @start = grep /^[0-9a-fA-F]+\s+[A-Z]\s+$start_symbol\s*$/, @symbols;
69 my @end = grep /^[0-9a-fA-F]+\s+[A-Z]\s+$end_symbol\s*$/, @symbols;
71 if(! defined $start[0] || ! defined $end[0]) {
72 die 'start ('.$start_symbol.') or end ('.$end_symbol.') symbol not found!';
75 my $start = $start[0];
78 $start =~ s/^([0-9a-fA-F]+).*$/$1/;
79 $end =~ s/^([0-9a-fA-F]+).*$/$1/;
81 #print "start of init area: $start\n";
82 #print "end if init area : $end\n";
84 $start = Math::BigInt->new("0x".$start);
85 $end = Math::BigInt->new("0x".$end);
89 while($_ = shift @symbols) {
90 if(/^([0-9a-fA-F]+)\s+[A-Z]\s+(\S+)/) {
91 my $addr = Math::BigInt->new("0x".$1);
93 if ( $symbol ne $start_symbol
94 && $symbol ne $end_symbol
95 && $addr->bcmp($start) >= 0
96 && $addr->bcmp($end) < 0) {
97 $init_syms{$symbol} = 1;
103 while($_ = shift @ARGV) {
106 # search for sections .text.* in object file
107 my @sections = split $/, qx{$hdr_objdump $file};
108 my $text_sections = '';
109 foreach $_ (@sections) {
110 if (/^\s*[0-9]+\s(\.text[.0-9a-zA-Z_]*)/) {
111 $text_sections .= " -j ".$1;
115 # disassemble object file
116 my @dump = split $/, qx{$dis_objdump $text_sections $file};
128 if (/^(\S+:[0-9]+)\s*$/) {
132 if (/^([0-9a-fA-F]+)\s+<(.*)>:$/) {
136 if (/^\s*([0-9a-fA-F]+):\s+R_\S+\s+(\S+\(.*\))\S*\s*$/) {
138 if ( defined $function
139 && $function !~ /^($ignore_funcs)(\(.*\))?$/
140 && defined $init_syms{$sym}) {
141 $source = $file unless defined $source;
142 (my $func_pretty = $function) =~ s/_GLOBAL__I\.\d+_//;
143 $func_pretty = `echo '$func_pretty' | ${target}c++filt`;
145 print STDERR "$source: $warn: $func_pretty uses initcall ($sym) from normal text section\n";