#!/usr/local/bin/perl # we make up an array of # $file{function_name}=filename; # $unres{filename}="func1 func2 ...." $debug=1; #$nm_func="parse_linux"; $nm_func="parse_solaris"; foreach (@ARGV) { &$nm_func($_); } foreach $file (sort keys %unres) { @a=split(/\s+/,$unres{$file}); %ff=(); foreach $func (@a) { $f=$file{$func}; $ff{$f}=1 if $f ne ""; } foreach $a (keys %ff) { $we_need{$file}.="$a "; } } foreach $file (sort keys %we_need) { # print " $file $we_need{$file}\n"; foreach $bit (split(/\s+/,$we_need{$file})) { push(@final,&walk($bit)); } foreach (@final) { $fin{$_}=1; } @final=""; foreach (sort keys %fin) { push(@final,$_); } print "$file: @final\n"; } sub walk { local($f)=@_; local(@a,%seen,@ret,$r); @ret=""; $f =~ s/^\s+//; $f =~ s/\s+$//; return "" if ($f =~ "^\s*$"); return(split(/\s/,$done{$f})) if defined ($done{$f}); return if $in{$f} > 0; $in{$f}++; push(@ret,$f); foreach $r (split(/\s+/,$we_need{$f})) { push(@ret,&walk($r)); } $in{$f}--; $done{$f}=join(" ",@ret); return(@ret); } sub parse_linux { local($name)=@_; open(IN,"nm $name|") || die "unable to run 'nn $name':$!\n"; while () { chop; next if /^\s*$/; if (/^[^[](.*):$/) { $file=$1; $file="$1.c" if /\[(.*).o\]/; print STDERR "$file\n"; $we_need{$file}=" "; next; } @a=split(/\s*\|\s*/); next unless $#a == 7; next unless $a[4] eq "GLOB"; if ($a[6] eq "UNDEF") { $unres{$file}.=$a[7]." "; } else { if ($file{$a[7]} ne "") { print STDERR "duplicate definition of $a[7],\n$file{$a[7]} and $file \n"; } else { $file{$a[7]}=$file; } } } close(IN); } sub parse_solaris { local($name)=@_; open(IN,"nm $name|") || die "unable to run 'nn $name':$!\n"; while () { chop; next if /^\s*$/; if (/^(\S+):$/) { $file=$1; #$file="$1.c" if $file =~ /^(.*).o$/; print STDERR "$file\n"; $we_need{$file}=" "; next; } @a=split(/\s*\|\s*/); next unless $#a == 7; next unless $a[4] eq "GLOB"; if ($a[6] eq "UNDEF") { $unres{$file}.=$a[7]." "; print STDERR "$file needs $a[7]\n" if $debug; } else { if ($file{$a[7]} ne "") { print STDERR "duplicate definition of $a[7],\n$file{$a[7]} and $file \n"; } else { $file{$a[7]}=$file; print STDERR "$file has $a[7]\n" if $debug; } } } close(IN); }