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:
authorChristopher Faylor <me@cgf.cx>2009-04-12 07:19:52 +0400
committerChristopher Faylor <me@cgf.cx>2009-04-12 07:19:52 +0400
commitedd090a2704aaf538c41cc97619c1d473b4916b2 (patch)
tree844ddc3a55e17cffac03a1342e30c9e15acf1453 /winsup/cygwin/mkimport
parent370a1171d8e7f3e93062815f53734f74a35ac817 (diff)
* mkimport: New script to perform all operations necessary to create
libcygwin.a. * rmsym: Delete. * newsym: Delete. * Makefile.in (toolopts): New variable which holds options relating to binutils/gcc tools. (speclib): Use toolopts. Add symbols to avoid copying to special libraries. (OBSOLETE_FUNCTIONS): Delete. (NEW_FUNCTIONS): Change to represent an argument to new mkimport script. (libcygwin.a): Use only new mkimport script to create libcygwin.a. Only rely on ${LIBCOS}. (*/lib*.a): Simplify speclib dependencies. (speclib): Accept toolchain options. Convert every argument to absolute path. Simplify parsing of nm output. Accommodate new exclude option.
Diffstat (limited to 'winsup/cygwin/mkimport')
-rwxr-xr-xwinsup/cygwin/mkimport80
1 files changed, 80 insertions, 0 deletions
diff --git a/winsup/cygwin/mkimport b/winsup/cygwin/mkimport
new file mode 100755
index 000000000..58c604180
--- /dev/null
+++ b/winsup/cygwin/mkimport
@@ -0,0 +1,80 @@
+#!/usr/bin/perl
+use strict;
+use File::Temp qw'tempdir';
+use File::Spec;
+use Getopt::Long;
+my $dir = tempdir(CLEANUP => 1);
+
+my ($ar, $as, $nm, $objcopy, %replace);
+GetOptions('ar=s'=>\$ar, 'as=s'=>\$as,'nm=s'=>\$nm, 'objcopy=s'=>\$objcopy, 'replace=s'=>\%replace);
+
+# Args::
+# 1) import lib to create
+# 2) input dll
+# 3...) extra objects to add
+
+$_ = File::Spec->rel2abs($_) for @ARGV;
+
+my $libdll = shift;
+my $inpdll = shift;
+
+open my $nm_fd, '-|', $nm, '-Apg', '--defined-only', $inpdll;
+my %text = ();
+my %import = ();
+my %symfile = ();
+while (<$nm_fd>) {
+ chomp;
+ my ($fn, $type, $sym) = /^$inpdll:(.*?):\S+\s+(\S)\s+(\S+)$/o;
+ next unless $fn;
+ $text{$fn} = $sym if $type eq 'T';
+ $import{$fn} = $sym if $type eq 'I';
+ $symfile{$sym} = $fn;
+}
+close $nm_fd or exit 1;
+
+for my $sym (keys %replace) {
+ my $fn;
+ my $_sym = '_' . $sym;
+ if (!defined($fn = $symfile{$_sym})) {
+ $fn = "$sym.o";
+ $text{$fn} = $_sym;
+ }
+ my $imp_sym = '__imp__' . $replace{$sym};
+ $import{$fn} = $imp_sym;
+}
+
+for my $f (keys %text) {
+ my $imp_sym = delete $import{$f};
+ my $glob_sym = $text{$f};
+ if (!defined $imp_sym) {
+ delete $text{$f};
+ } elsif ($imp_sym eq '__imp__') {
+ $text{$f} = 0;
+ } else {
+ $text{$f} = 1;
+ open my $as_fd, '|-', $as, '-o', "$dir/t-$f", "-";
+ print $as_fd <<EOF;
+ .extern $imp_sym
+ .global $glob_sym
+$glob_sym:
+ jmp *$imp_sym
+EOF
+ close $as_fd or exit 1;
+ }
+}
+
+chdir $dir or die "$0: couldn't cd to $dir - $!\n";
+system $ar, 'x', $inpdll;
+exit 1 if $?;
+
+for my $f (keys %text) {
+ if (!$text{$f}) {
+ unlink $f;
+ } else {
+ system $objcopy, '-R', '.text', $f and exit 1;
+ system $objcopy, '-R', '.bss', '-R', '.data', "t-$f" and exit 1;
+ }
+}
+
+unlink $libdll;
+exec $ar, 'crus', $libdll, glob('*.o'), @ARGV;