#!/usr/bin/env perl

my @dirstack = (".");
my %symbols_defined;
my %symbols_needed;

sub visit_file {
    my ($file) = @_;
    open(my $fh, "-|", "nm $file") || die;

    while (my $entry = readline($fh)) {
        chomp($entry);
        my @elem = split(" ", $entry);
        my $addr, $type, $name;
        if ($#elem == 2) {
            ($addr, $type, $name) = split(" ", $entry);
        } else {
            ($type, $name) = split(" ", $entry);
        }
        if ($type eq 'T' || $type eq 'D' || $type eq 'B' || $type eq 'R') {
#            print "defines type $type name $name\n";
            $symbols_defined{$name} = $symbols_defined{$name} . " " . $file;
        } elsif ($type eq 'U' || $type eq 'C') {
#            print "needs type $type name $name\n";
            $symbols_needed{$name}++;
        }
    }
    close $fh;
}


sub visit_dir {
    my ($cur) = @_;
    opendir(my $dh, $cur) || die;

    while (my $entry = readdir $dh) {
        if ($entry ne "." && $entry ne "..") {
            $entry = $cur . "/" . $entry;
            if ( -d $entry) {
                push(@dirstack, $entry);
            } elsif ($entry =~ m/.*\.o$/) {
#                print "object $entry\n";
                visit_file($entry);
            }
        }
    }
    closedir $dh;
}

while (my $cur = pop(@dirstack)) {
    visit_dir($cur);
}

foreach $symbol (sort(keys %symbols_defined)) {
    if ($symbols_needed{$symbol} == 0) {
        print "$symbol ($symbols_defined{$symbol})\n";
    }
}
