2009-01-02 07:57:14 +01:00
|
|
|
#!/usr/bin/perl
|
|
|
|
use Getopt::Long;
|
|
|
|
use File::Temp qw'tempdir';
|
|
|
|
use File::Basename;
|
2009-04-09 23:02:53 +02:00
|
|
|
use Cwd;
|
2009-01-02 07:57:14 +01:00
|
|
|
use strict;
|
|
|
|
|
2009-04-09 23:02:53 +02:00
|
|
|
sub dllname($;$);
|
2009-01-02 07:57:14 +01:00
|
|
|
|
2009-04-09 23:02:53 +02:00
|
|
|
my $static;
|
|
|
|
my $exclude;
|
|
|
|
|
|
|
|
GetOptions('static!'=>\$static, 'v|exclude!'=>\$exclude);
|
2009-03-28 05:55:36 +01:00
|
|
|
|
2009-04-09 23:02:53 +02:00
|
|
|
my $nm = shift;
|
|
|
|
my $ar = shift;
|
|
|
|
my $libdll = Cwd::abs_path(shift @ARGV);
|
|
|
|
my $lib = Cwd::abs_path(pop @ARGV);
|
|
|
|
|
|
|
|
open my $nm_fd, '-|', $nm, '-Ap', '--defined-only', @ARGV, $libdll or
|
2009-01-02 07:57:14 +01:00
|
|
|
die "$0: execution of $nm for object files failed - $!\n";
|
|
|
|
|
2009-04-09 23:02:53 +02:00
|
|
|
my %match_syms = ();
|
|
|
|
my $symfiles = ();
|
|
|
|
my $lastfn;
|
|
|
|
my %extract = ();
|
2009-01-02 07:57:14 +01:00
|
|
|
while (<$nm_fd>) {
|
2009-04-09 23:02:53 +02:00
|
|
|
study;
|
|
|
|
m%^\Q$libdll\E:([^:]*):\d+ i \.idata\$([56])% and do {
|
|
|
|
next;
|
|
|
|
};
|
|
|
|
m%^\Q$libdll\E:[^:]*:\d+ I (__head_.*)$% and do {
|
|
|
|
next;
|
|
|
|
};
|
|
|
|
next unless m%^([^:]*):([^:]*(?=:))?.* [DTI] (.*)%o;
|
|
|
|
if ($1 ne $libdll) {
|
|
|
|
$match_syms{$3} = 1;
|
|
|
|
} elsif ($match_syms{$3} ? !$exclude : $exclude) {
|
|
|
|
$extract{$2} = 1;
|
|
|
|
}
|
2009-01-02 07:57:14 +01:00
|
|
|
}
|
|
|
|
close $nm_fd;
|
|
|
|
|
2009-04-09 23:02:53 +02:00
|
|
|
%extract or die "$0: couldn't find symbols for $lib\n";
|
|
|
|
|
|
|
|
my $dir = tempdir(CLEANUP => 1);
|
2009-01-02 07:57:14 +01:00
|
|
|
|
2009-04-09 23:02:53 +02:00
|
|
|
chdir $dir;
|
|
|
|
# print join(' ', '+', $ar, 'x', sort keys %extract), "\n";
|
|
|
|
my $res = system $ar, 'x', $libdll, sort keys %extract;
|
|
|
|
die "$0: $ar extraction exited with non-zero status\n" if $res;
|
|
|
|
unlink $lib;
|
|
|
|
exec $ar, 'crus', $lib, sort keys %extract;
|