newlib/winsup/cygwin/mkimport
Christopher Faylor edd090a270 * 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.
2009-04-12 03:19:52 +00:00

81 lines
1.7 KiB
Perl
Executable File

#!/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;