Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'winsup/cygwin/scripts/speclib')
-rwxr-xr-xwinsup/cygwin/scripts/speclib84
1 files changed, 84 insertions, 0 deletions
diff --git a/winsup/cygwin/scripts/speclib b/winsup/cygwin/scripts/speclib
new file mode 100755
index 000000000..e6d4d8e94
--- /dev/null
+++ b/winsup/cygwin/scripts/speclib
@@ -0,0 +1,84 @@
+#!/usr/bin/perl
+use Getopt::Long;
+use File::Temp qw'tempdir';
+use File::Basename;
+use File::Spec;
+use strict;
+
+sub dllname($;$);
+
+my $static;
+my $inverse;
+my @exclude;
+
+my ($cpu, $ar, $as, $nm, $objcopy);
+GetOptions('exclude=s'=>\@exclude, 'static!'=>\$static, 'v!'=>\$inverse,
+ 'cpu=s'=>\$cpu, 'ar=s'=>\$ar, 'as=s'=>\$as,'nm=s'=>\$nm, 'objcopy=s'=>\$objcopy);
+
+$_ = File::Spec->rel2abs($_) for @ARGV;
+
+my $libdll = shift;
+my $lib = pop;
+# FIXME? Do other (non-32 bit) arches on Windows still use symbol prefixes?
+my $sym_prefix = '';
+(my $iname = basename $lib) =~ s/\.a$//o;
+$iname = $sym_prefix . $iname . '_dll_iname';
+
+open my $nm_fd, '-|', $nm, '-Apg', '--defined-only', @ARGV, $libdll or
+ die "$0: execution of $nm for object files failed - $!\n";
+
+my %match_syms = ();
+my $symfiles = ();
+my $lastfn;
+my %extract = ();
+my $exclude_regex = @exclude ? join('|', @exclude) : '\\UnLiKeLy//';
+$exclude_regex = qr/$exclude_regex/;
+my $dllname;
+while (<$nm_fd>) {
+ study;
+ if (/ I _?(.*)_dll_iname/o) {
+ $dllname = $1;
+ } else {
+ my ($file, $member, $symbol) = m%^([^:]*):([^:]*(?=:))?.* T (.*)%o;
+ next if !defined($symbol) || $symbol =~ $exclude_regex;
+ if ($file ne $libdll) {
+ $match_syms{$symbol} = 1;
+ } elsif ($match_syms{$symbol} ? !$inverse : $inverse) {
+ $extract{$member} = 1;
+ }
+ }
+}
+close $nm_fd;
+
+
+%extract or die "$0: couldn't find symbols for $lib\n";
+
+my $dir = tempdir(CLEANUP => 1);
+
+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;
+
+# Add a dummy .idata object for libtool so that it will think
+# this library is an import library.
+my $iname_o = 'd000000.o';
+$extract{$iname_o} = 1;
+open my $as_fd, '|-', $as, '-R', '-o', $iname_o, "-";
+print $as_fd <<EOF;
+ .section .idata\$7
+.global $iname
+$iname: .asciz "$dllname.dll"
+EOF
+close $as_fd or exit 1;
+system $objcopy, '-j', '.idata$7', $iname_o;
+
+$res = system $ar, 'crus', $lib, sort keys %extract;
+unlink keys %extract;
+die "$0: ar creation of $lib exited with non-zero status\n" if $res;
+exit 0;
+
+END {
+ chdir '/tmp'; # Allow $dir directory removal on Windows
+}