1#!/usr/local/bin/perl
2
3# we make up an array of
4# $file{function_name}=filename;
5# $unres{filename}="func1 func2 ...."
6$debug=1;
7#$nm_func="parse_linux";
8$nm_func="parse_solaris";
9
10foreach (@ARGV)
11	{
12	&$nm_func($_);
13	}
14
15foreach $file (sort keys %unres)
16	{
17	@a=split(/\s+/,$unres{$file});
18	%ff=();
19	foreach $func (@a)
20		{
21		$f=$file{$func};
22		$ff{$f}=1 if $f ne "";
23		}
24
25	foreach $a (keys %ff)
26		{ $we_need{$file}.="$a "; }
27	}
28
29foreach $file (sort keys %we_need)
30	{
31#	print "	$file $we_need{$file}\n";
32	foreach $bit (split(/\s+/,$we_need{$file}))
33		{ push(@final,&walk($bit)); }
34
35	foreach (@final) { $fin{$_}=1; }
36	@final="";
37	foreach (sort keys %fin)
38		{ push(@final,$_); }
39
40	print "$file: @final\n";
41	}
42
43sub walk
44	{
45	local($f)=@_;
46	local(@a,%seen,@ret,$r);
47
48	@ret="";
49	$f =~ s/^\s+//;
50	$f =~ s/\s+$//;
51	return "" if ($f =~ "^\s*$");
52
53	return(split(/\s/,$done{$f})) if defined ($done{$f});
54
55	return if $in{$f} > 0;
56	$in{$f}++;
57	push(@ret,$f);
58	foreach $r (split(/\s+/,$we_need{$f}))
59		{
60		push(@ret,&walk($r));
61		}
62	$in{$f}--;
63	$done{$f}=join(" ",@ret);
64	return(@ret);
65	}
66
67sub parse_linux
68	{
69	local($name)=@_;
70
71	open(IN,"nm $name|") || die "unable to run 'nn $name':$!\n";
72	while (<IN>)
73		{
74		chop;
75		next if /^\s*$/;
76		if (/^[^[](.*):$/)
77			{
78			$file=$1;
79			$file="$1.c" if /\[(.*).o\]/;
80			print STDERR "$file\n";
81			$we_need{$file}=" ";
82			next;
83			}
84
85		@a=split(/\s*\|\s*/);
86		next unless $#a == 7;
87		next unless $a[4] eq "GLOB";
88		if ($a[6] eq "UNDEF")
89			{
90			$unres{$file}.=$a[7]." ";
91			}
92		else
93			{
94			if ($file{$a[7]} ne "")
95				{
96				print STDERR "duplicate definition of $a[7],\n$file{$a[7]} and $file \n";
97				}
98			else
99				{
100				$file{$a[7]}=$file;
101				}
102			}
103		}
104	close(IN);
105	}
106
107sub parse_solaris
108	{
109	local($name)=@_;
110
111	open(IN,"nm $name|") || die "unable to run 'nn $name':$!\n";
112	while (<IN>)
113		{
114		chop;
115		next if /^\s*$/;
116		if (/^(\S+):$/)
117			{
118			$file=$1;
119			#$file="$1.c" if $file =~ /^(.*).o$/;
120			print STDERR "$file\n";
121			$we_need{$file}=" ";
122			next;
123			}
124		@a=split(/\s*\|\s*/);
125		next unless $#a == 7;
126		next unless $a[4] eq "GLOB";
127		if ($a[6] eq "UNDEF")
128			{
129			$unres{$file}.=$a[7]." ";
130			print STDERR "$file needs $a[7]\n" if $debug;
131			}
132		else
133			{
134			if ($file{$a[7]} ne "")
135				{
136				print STDERR "duplicate definition of $a[7],\n$file{$a[7]} and $file \n";
137				}
138			else
139				{
140				$file{$a[7]}=$file;
141				print STDERR "$file has $a[7]\n" if $debug;
142				}
143			}
144		}
145	close(IN);
146	}
147
148