155714Skris#!/usr/local/bin/perl
255714Skris
355714Skris# we make up an array of
455714Skris# $file{function_name}=filename;
555714Skris# $unres{filename}="func1 func2 ...."
655714Skris$debug=1;
755714Skris#$nm_func="parse_linux";
855714Skris$nm_func="parse_solaris";
955714Skris
1055714Skrisforeach (@ARGV)
1155714Skris	{
1255714Skris	&$nm_func($_);
1355714Skris	}
1455714Skris
1555714Skrisforeach $file (sort keys %unres)
1655714Skris	{
1755714Skris	@a=split(/\s+/,$unres{$file});
1855714Skris	%ff=();
1955714Skris	foreach $func (@a)
2055714Skris		{
2155714Skris		$f=$file{$func};
2255714Skris		$ff{$f}=1 if $f ne "";
2355714Skris		}
2455714Skris
2555714Skris	foreach $a (keys %ff)
2655714Skris		{ $we_need{$file}.="$a "; }
2755714Skris	}
2855714Skris
2955714Skrisforeach $file (sort keys %we_need)
3055714Skris	{
3155714Skris#	print "	$file $we_need{$file}\n";
3255714Skris	foreach $bit (split(/\s+/,$we_need{$file}))
3355714Skris		{ push(@final,&walk($bit)); }
3455714Skris
3555714Skris	foreach (@final) { $fin{$_}=1; }
3655714Skris	@final="";
3755714Skris	foreach (sort keys %fin)
3855714Skris		{ push(@final,$_); }
3955714Skris
4055714Skris	print "$file: @final\n";
4155714Skris	}
4255714Skris
4355714Skrissub walk
4455714Skris	{
4555714Skris	local($f)=@_;
4655714Skris	local(@a,%seen,@ret,$r);
4755714Skris
4855714Skris	@ret="";
4955714Skris	$f =~ s/^\s+//;
5055714Skris	$f =~ s/\s+$//;
5155714Skris	return "" if ($f =~ "^\s*$");
5255714Skris
5355714Skris	return(split(/\s/,$done{$f})) if defined ($done{$f});
5455714Skris
5555714Skris	return if $in{$f} > 0;
5655714Skris	$in{$f}++;
5755714Skris	push(@ret,$f);
5855714Skris	foreach $r (split(/\s+/,$we_need{$f}))
5955714Skris		{
6055714Skris		push(@ret,&walk($r));
6155714Skris		}
6255714Skris	$in{$f}--;
6355714Skris	$done{$f}=join(" ",@ret);
6455714Skris	return(@ret);
6555714Skris	}
6655714Skris
6755714Skrissub parse_linux
6855714Skris	{
6955714Skris	local($name)=@_;
7055714Skris
7155714Skris	open(IN,"nm $name|") || die "unable to run 'nn $name':$!\n";
7255714Skris	while (<IN>)
7355714Skris		{
7455714Skris		chop;
7555714Skris		next if /^\s*$/;
7655714Skris		if (/^[^[](.*):$/)
7755714Skris			{
7855714Skris			$file=$1;
7955714Skris			$file="$1.c" if /\[(.*).o\]/;
8055714Skris			print STDERR "$file\n";
8155714Skris			$we_need{$file}=" ";
8255714Skris			next;
8355714Skris			}
8455714Skris
8555714Skris		@a=split(/\s*\|\s*/);
8655714Skris		next unless $#a == 7;
8755714Skris		next unless $a[4] eq "GLOB";
8855714Skris		if ($a[6] eq "UNDEF")
8955714Skris			{
9055714Skris			$unres{$file}.=$a[7]." ";
9155714Skris			}
9255714Skris		else
9355714Skris			{
9455714Skris			if ($file{$a[7]} ne "")
9555714Skris				{
9655714Skris				print STDERR "duplicate definition of $a[7],\n$file{$a[7]} and $file \n";
9755714Skris				}
9855714Skris			else
9955714Skris				{
10055714Skris				$file{$a[7]}=$file;
10155714Skris				}
10255714Skris			}
10355714Skris		}
10455714Skris	close(IN);
10555714Skris	}
10655714Skris
10755714Skrissub parse_solaris
10855714Skris	{
10955714Skris	local($name)=@_;
11055714Skris
11155714Skris	open(IN,"nm $name|") || die "unable to run 'nn $name':$!\n";
11255714Skris	while (<IN>)
11355714Skris		{
11455714Skris		chop;
11555714Skris		next if /^\s*$/;
11655714Skris		if (/^(\S+):$/)
11755714Skris			{
11855714Skris			$file=$1;
11955714Skris			#$file="$1.c" if $file =~ /^(.*).o$/;
12055714Skris			print STDERR "$file\n";
12155714Skris			$we_need{$file}=" ";
12255714Skris			next;
12355714Skris			}
12455714Skris		@a=split(/\s*\|\s*/);
12555714Skris		next unless $#a == 7;
12655714Skris		next unless $a[4] eq "GLOB";
12755714Skris		if ($a[6] eq "UNDEF")
12855714Skris			{
12955714Skris			$unres{$file}.=$a[7]." ";
13055714Skris			print STDERR "$file needs $a[7]\n" if $debug;
13155714Skris			}
13255714Skris		else
13355714Skris			{
13455714Skris			if ($file{$a[7]} ne "")
13555714Skris				{
13655714Skris				print STDERR "duplicate definition of $a[7],\n$file{$a[7]} and $file \n";
13755714Skris				}
13855714Skris			else
13955714Skris				{
14055714Skris				$file{$a[7]}=$file;
14155714Skris				print STDERR "$file has $a[7]\n" if $debug;
14255714Skris				}
14355714Skris			}
14455714Skris		}
14555714Skris	close(IN);
14655714Skris	}
14755714Skris
148