#! /usr/bin/perl
use strict;
use warnings;
use Getopt::Std;
our($opt_r, $opt_v);
getopts('rv');
my %objs;
my %syms;
my %depsyms;
my %objdefs;
open NM, "nm -Ag @ARGV |" or die "$!";
while(<NM>){
/^(.*:)?(.*):[[:xdigit:] ]+([A-Z])\s+(.*)$/ or next;
my($obj, $type, $sym) = ($2, $3, $4);
if($type eq 'U'){
$objs{$obj}{$sym}++;
$depsyms{$sym}{$obj}++;
} else {
@{$objs{$obj}}{()} = ();
$syms{$sym} = $obj;
$objdefs{$obj}{$sym}++;
}
}
close NM;
for my $obj (sort keys %objs) {
my %deps;
if (!$opt_r) {
for my $sym (keys %{$objs{$obj}}) {
next if not defined $syms{$sym};
$deps{$syms{$sym}}{$sym}++;
}
} else {
for my $sym (keys %{$objdefs{$obj}}) {
next if not defined $depsyms{$sym};
for my $o (keys %{$depsyms{$sym}}) {
map $deps{$o}{$_}++,
grep defined $objdefs{$obj}{$_}, keys %{$objs{$o}};
}
}
}
print "$obj:\n";
for my $dep (sort keys %deps) {
print "\t$dep\n";
$opt_v and print "\t\t$_\n" for sort keys %{$deps{$dep}};
}
}