#!/usr/bin/perl -w

# Libraries to re-order for startup speed ...

@libraries = (
	      'libsw%%li.so',  'sw',   'sw.lib',
	      'libsfx%%li.so', 'sfx2', 'sfx.lib',
	      'libsvx%%li.so', 'svx',  'svx.lib'
	     );

sub find_bindings
{
    my $file;
    my $ldname = shift;
    my %binds;

    print "Reading bindings for: $ldname\n";
    open ($file, $output) || die "Can't open $output: $!";
    while (<$file>) {
	/$ldname:\s+.*\`([^\']*)\'/ || next;
	my $sym = $1;
	my $count;
	$count = ++$binds{$sym};
    }
    close ($file);

    return %binds;
}

sub make_path
{
    my $base = shift;
    my $fname = shift;

    print "Base '$base'\n";
    return ($base . "/unxlngi4.pro/slb/" . $fname);
}

sub read_object_list
{
    my $base = shift;
    my $fname = shift;
    my $path;
    my %objs;

    $path = make_path ($base, $fname);

    my $file;
    open ($file, $path) || die "Can't open $path: $!\n";
    while (<$file>) {
	chomp;
	$_ eq '' && next;
	$objs{$_} = 0;
    }
    close ($file);

    return %objs;
}

sub count_symbols
{
    my $path = shift;
    my $bindings = shift;
    my $count = 0;
    my $pipe;

    print ".";

# FIXME - we need to check the type of re-location I think [!?] - needs to be a provides ..
    open $pipe, "nm $path|" || die "Can't objdump $path: $!";
    while (<$pipe>) {
	/\s+([^\s]+)$/ || next;
# hard to know which is best - this seems so,
#	/[TGDBRS]\s+([^\s]+)$/ || next;
	if (exists $bindings->{$1}) {
	    $count = $count + $bindings->{$1};
	}
    }
    close $pipe;

    return $count;
}

if (@ARGV < 1) {
    print "Syntax:\n";
    print "  reorder-link <path-to-output>\n";
    print "  where output is generated by LD_DEBUG=bindings\n";
    exit (1);
}

$output = shift @ARGV;

{
    print "Sucking env from setup\n";
    open ($Vars, ". ./setup ; set|") || die "Can't find setup: $!";
    while (<$Vars>) {
	/([^=]*)=(.*)/ || next;
	$setup_vars{$1} = $2;
    }
    close ($Vars);
}

# Hack - clobber for test setup
$setup_vars{'OOBUILDDIR'} = '/opt/OpenOffice/OOO_STABLE_1';

while (@libraries) {
    my $ldname  = shift @libraries;
    my $path    = shift @libraries;
    my $libname = shift @libraries;

    $ldname =~ s/%%/641/;

    my $base = $setup_vars{'OOBUILDDIR'} . "/$path";

    my %bindings = find_bindings ($ldname);
    my %objects = read_object_list ($base, $libname);
    my $obj;
    
    printf "Counting symbols ";
    foreach $obj (keys %objects) {
	$objects{$obj} = count_symbols ("$base/$obj", \%bindings);
    }
    printf "\n";
   
    my $out_path = make_path ($base, "$libname.sorted");
    my $out_file;
    print "Writing new map to $out_path ...\n";
    open ($out_file, ">$out_path") || die "Can't open $out_path: $!";

    foreach $obj (sort { $objects{$b} <=> $objects{$a} } keys %objects) {
	print $objects{$obj}. ", ";
	print $out_file "$obj\n";
    }
    close ($out_file);
    print "\ndone\n";
}
