From 59328e28c4a925d81c95c72002ba2d6118aa28d6 Mon Sep 17 00:00:00 2001 From: Christopher Faylor Date: Thu, 9 Apr 2009 21:02:53 +0000 Subject: [PATCH] * speclib: Semi-revert to previous version but don't try to generate well-formed import library. Instead, just extract appropriate symbols and let later libcygwin.a on link line fill in the rest of the import stuff. * gendef: Hopefully no-op modification to allow easier post-processing on symbol values. --- winsup/cygwin/ChangeLog | 9 +++++ winsup/cygwin/Makefile.in | 14 ++++---- winsup/cygwin/gendef | 18 +++++----- winsup/cygwin/speclib | 75 ++++++++++++++++++++------------------- 4 files changed, 64 insertions(+), 52 deletions(-) diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 7ed7942c7..8a9a76921 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,12 @@ +2009-04-09 Christopher Faylor + + * speclib: Semi-revert to previous version but don't try to generate + well-formed import library. Instead, just extract appropriate symbols + and let later libcygwin.a on link line fill in the rest of the import + stuff. + * gendef: Hopefully no-op modification to allow easier post-processing + on symbol values. + 2009-04-09 Corinna Vinschen * syscalls.cc (try_to_bin): Use tmp_pathbuf buffer to allocate infobuf diff --git a/winsup/cygwin/Makefile.in b/winsup/cygwin/Makefile.in index d9c3b87cc..63458cf9d 100644 --- a/winsup/cygwin/Makefile.in +++ b/winsup/cygwin/Makefile.in @@ -105,7 +105,7 @@ LIBGMON_A:=libgmon.a CYGWIN_START:=crt0.o GMON_START:=gcrt0.o -speclib=${word 1, $^} "${NM}" "$(DLLTOOL)" $(wordlist 2, $(words $^), $^) +speclib=${word 1, $^} "${NM}" "${AR}" $(wordlist 2, $(words $^), $^) # Some things want these from libc, but they have their own static # data which apps can get to, which is a pain in the dll, so we @@ -442,22 +442,22 @@ shared.o: shared_info_magic.h $(srcdir)/devices.cc: gendevices devices.in devices.h ${wordlist 1,2,$^} $@ -${CURDIR}/libc.a: speclib ${DEF_FILE} ./libm.a libpthread.a libutil.a +${CURDIR}/libc.a: speclib ${LIB_NAME} ./libm.a libpthread.a libutil.a ${speclib} -v ${@F} -${CURDIR}/libm.a: speclib ${DEF_FILE} $(LIBM) +${CURDIR}/libm.a: speclib ${LIB_NAME} $(LIBM) ${speclib} ${@F} -libpthread.a: speclib ${DEF_FILE} pthread.o thread.o +libpthread.a: speclib ${LIB_NAME} pthread.o thread.o ${speclib} ${@F} -libutil.a: speclib ${DEF_FILE} bsdlib.o +libutil.a: speclib ${LIB_NAME} bsdlib.o ${speclib} ${@F} -libdl.a: speclib ${DEF_FILE} dlfcn.o +libdl.a: speclib ${LIB_NAME} dlfcn.o ${speclib} ${@F} -libresolv.a: speclib ${DEF_FILE} minires.o +libresolv.a: speclib ${LIB_NAME} minires.o ${speclib} ${@F} ${EXTRALIBS}: lib%.a: %.o diff --git a/winsup/cygwin/gendef b/winsup/cygwin/gendef index d2f454362..7c17a11ee 100755 --- a/winsup/cygwin/gendef +++ b/winsup/cygwin/gendef @@ -34,13 +34,13 @@ close(IN); my %sigfe = (); my @data = (); my @nosigfuncs = (); -my @out = (); +my @text = (); for (@in) { - /\sDATA$/o and do { - push(@data, $_); + chomp; + s/\sDATA$//o and do { + push @data, $_; next; }; - chomp; if (/=/o) { if (s/\s+NOSIGFE\s*$//) { # nothing @@ -63,16 +63,18 @@ for (@in) { s/(\S)\s+(\S)/$1 $2/go; s/(\S)\s+$/$1/o; s/^\s+(\S)/$1/o; - push(@out, $_ . "\n"); + push @text, $_; } -for (@out) { +for (@text) { my ($alias, $func) = /^(\S+) = (\S+)\s*$/o; - $_ = $alias . ' = ' . $sigfe{$func} . "\n" + $_ = $alias . ' = ' . $sigfe{$func} if defined($func) && $sigfe{$func}; } + open(OUT, '>', $out) or die "$0: couldn't open \"$out\" - $!\n"; -print OUT @top, @data, @out; +push @top, (map {$_ . " DATA\n"} @data), (map {$_ . "\n"} @text); +print OUT @top; close OUT; open(SIGFE, '>', $sigfe) or die "$0: couldn't open sigfe file \"$sigfe\" - $!\n"; diff --git a/winsup/cygwin/speclib b/winsup/cygwin/speclib index bea9cbc4a..e1e9ebcad 100755 --- a/winsup/cygwin/speclib +++ b/winsup/cygwin/speclib @@ -2,51 +2,52 @@ use Getopt::Long; use File::Temp qw'tempdir'; use File::Basename; +use Cwd; use strict; +sub dllname($;$); + +my $static; +my $exclude; + +GetOptions('static!'=>\$static, 'v|exclude!'=>\$exclude); + my $nm = shift; -my $dlltool = shift; -my $def = shift; -my $lib = pop; +my $ar = shift; +my $libdll = Cwd::abs_path(shift @ARGV); +my $lib = Cwd::abs_path(pop @ARGV); -my $inverse; -if ($ARGV[$#ARGV] ne '-v') { - $inverse = 0; -} else { - $inverse = 1; - $#ARGV--; -} - -open my $def_fd, '<', $def or die "$0: couldn't open \"$def\" - $!\n"; -my %defsyms = (); -my $newdef = ''; -while (<$def_fd>) { - if (/^\s*(?:EXPORTS\b|LIBRARY\b|\s*$)/o) { - $newdef .= $_; - } else { - my $sym = (split ' ')[0]; - $defsyms{$sym} = $_; - } -} -close $def_fd; - -open my $nm_fd, '-|', $nm, '-pg', '--defined-only', @ARGV or +open my $nm_fd, '-|', $nm, '-Ap', '--defined-only', @ARGV, $libdll or die "$0: execution of $nm for object files failed - $!\n"; +my %match_syms = (); +my $symfiles = (); +my $lastfn; +my %extract = (); while (<$nm_fd>) { - next unless /\S+\s+[A-Z]+\s+_(.*)$/o; - if ($inverse) { - delete $defsyms{$1}; - } else { - $newdef .= $defsyms{$1} if exists $defsyms{$1}; - } + 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; + } } close $nm_fd; -$newdef .= join '', sort values %defsyms if $inverse; +%extract or die "$0: couldn't find symbols for $lib\n"; -open my $dlltool_fd, '|-', $dlltool, '-d', '/proc/self/fd/0', '-D', 'cygwin1.dll', '-l', $lib or - die "$0: couldn't start dlltool - $dlltool - $!\n"; -print $dlltool_fd $newdef; -close $dlltool_fd or exit 1; -exit 0; +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; +exec $ar, 'crus', $lib, sort keys %extract;