From edd090a2704aaf538c41cc97619c1d473b4916b2 Mon Sep 17 00:00:00 2001 From: Christopher Faylor Date: Sun, 12 Apr 2009 03:19:52 +0000 Subject: [PATCH] * 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. --- winsup/cygwin/ChangeLog | 20 ++++++ winsup/cygwin/Makefile.in | 143 +++++++++++++++++++------------------- winsup/cygwin/mkimport | 80 +++++++++++++++++++++ winsup/cygwin/newsym | 39 ----------- winsup/cygwin/rmsym | 9 --- winsup/cygwin/speclib | 36 +++++----- 6 files changed, 188 insertions(+), 139 deletions(-) create mode 100755 winsup/cygwin/mkimport delete mode 100755 winsup/cygwin/newsym delete mode 100755 winsup/cygwin/rmsym diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index ad622a212..8050487bc 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,23 @@ +2009-04-11 Christopher Faylor + + * 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-11 Dave Korn * include/stdint.h (INTPTR_MIN, INTPTR_MAX): Add 'L' suffix. diff --git a/winsup/cygwin/Makefile.in b/winsup/cygwin/Makefile.in index 63458cf9d..2b8fb48a7 100644 --- a/winsup/cygwin/Makefile.in +++ b/winsup/cygwin/Makefile.in @@ -105,7 +105,14 @@ LIBGMON_A:=libgmon.a CYGWIN_START:=crt0.o GMON_START:=gcrt0.o -speclib=${word 1, $^} "${NM}" "${AR}" $(wordlist 2, $(words $^), $^) +toolopts:=--ar=${AR} --as=${AS} --nm=${NM} --objcopy=${OBJCOPY} +speclib=\ + ${srcdir}/speclib ${toolopts} \ + --exclude='cygwin' \ + --exclude='(?i:dll)' \ + --exclude='reloc' \ + --exclude='^_main$$' \ + $^ # 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 @@ -162,67 +169,60 @@ EXCLUDE_STATIC_OFILES:=$(addprefix --exclude=,\ GMON_OFILES:=gmon.o mcount.o profil.o -OBSOLETE_FUNCTIONS:=open acl aclcheck aclfrommode aclfrompbits \ - aclfromtext aclsort acltomode acltopbits \ - acltotext chown facl fchown fcntl fdopen fgetpos fopen \ - freopen fseeko fsetpos fstat ftello ftruncate \ - getegid geteuid getgid getgrent getgrgid getgrnam \ - getgroups getpwuid getpwuid_r getuid initgroups \ - lchown lseek lstat mknod mmap seekdir setegid seteuid \ - setgid setgroups setregid setreuid setuid stat \ - telldir tmpfile truncate timezone - -NEW_FUNCTIONS:=open _open64 \ - acl _acl32 \ - aclcheck _aclcheck32 \ - aclfrommode _aclfrommode32 \ - aclfrompbits _aclfrompbits32 \ - aclfromtext _aclfromtext32 \ - aclsort _aclsort32 \ - acltomode _acltomode32 \ - acltopbits _acltopbits32 \ - acltotext _acltotext32 \ - chown _chown32 \ - facl _facl32 \ - fchown _fchown32 \ - fcntl _fcntl64 \ - fdopen _fdopen64 \ - fgetpos _fgetpos64 \ - fopen _fopen64 \ - freopen _freopen64 \ - fseeko _fseeko64 \ - fsetpos _fsetpos64 \ - fstat _fstat64 \ - ftello _ftello64 \ - ftruncate _ftruncate64 \ - getegid _getegid32 \ - geteuid _geteuid32 \ - getgid _getgid32 \ - getgrent _getgrent32 \ - getgrgid _getgrgid32 \ - getgrnam _getgrnam32 \ - getgroups _getgroups32 \ - getpwuid _getpwuid32 \ - getpwuid_r _getpwuid_r32 \ - getuid _getuid32 \ - initgroups _initgroups32 \ - lchown _lchown32 \ - lseek _lseek64 \ - lstat _lstat64 \ - mknod _mknod32 \ - mmap _mmap64 \ - seekdir _seekdir64 \ - setegid _setegid32 \ - seteuid _seteuid32 \ - setgid _setgid32 \ - setgroups _setgroups32 \ - setregid _setregid32 \ - setreuid _setreuid32 \ - setuid _setuid32 \ - stat _stat64 \ - telldir _telldir64 \ - tmpfile _tmpfile64 \ - truncate _truncate64 +NEW_FUNCTIONS:=$(addprefix --replace=,\ + acl=_acl32 \ + aclcheck=_aclcheck32 \ + aclfrommode=_aclfrommode32 \ + aclfrompbits=_aclfrompbits32 \ + aclfromtext=_aclfromtext32 \ + aclsort=_aclsort32 \ + acltomode=_acltomode32 \ + acltopbits=_acltopbits32 \ + acltotext=_acltotext32 \ + chown=_chown32 \ + facl=_facl32 \ + fchown=_fchown32 \ + fcntl=_fcntl64 \ + fdopen=_fdopen64 \ + fgetpos=_fgetpos64 \ + fopen=_fopen64 \ + freopen=_freopen64 \ + fseeko=_fseeko64 \ + fsetpos=_fsetpos64 \ + fstat=_fstat64 \ + ftello=_ftello64 \ + ftruncate=_ftruncate64 \ + getegid=_getegid32 \ + geteuid=_geteuid32 \ + getgid=_getgid32 \ + getgrent=_getgrent32 \ + getgrgid=_getgrgid32 \ + getgrnam=_getgrnam32 \ + getgroups=_getgroups32 \ + getpwuid=_getpwuid32 \ + getpwuid_r=_getpwuid_r32 \ + getuid=_getuid32 \ + initgroups=_initgroups32 \ + lchown=_lchown32 \ + lseek=_lseek64 \ + lstat=_lstat64 \ + mknod=_mknod32 \ + mmap=_mmap64 \ + open=_open64 \ + seekdir=_seekdir64 \ + setegid=_setegid32 \ + seteuid=_seteuid32 \ + setgid=_setgid32 \ + setgroups=_setgroups32 \ + setregid=_setregid32 \ + setreuid=_setreuid32 \ + setuid=_setuid32 \ + stat=_stat64 \ + telldir=_telldir64 \ + timezone= \ + tmpfile=_tmpfile64 \ + truncate=_truncate64 \ +) API_VER:=$(srcdir)/include/cygwin/version.h @@ -396,11 +396,8 @@ $(TEST_DLL_NAME): $(LDSCRIPT) dllfixdbg $(DLL_OFILES) $(DLL_IMPORTS) $(LIBSERVER @ln -f $@ new-$(DLL_NAME) # Rule to build libcygwin.a -$(LIB_NAME): rmsym newsym $(TEST_DLL_NAME) $(LIBCOS) - /bin/sh ${word 1,$^} ./cygdll.a "$(NM)" "$(AR)" $(OBSOLETE_FUNCTIONS) || exit 0 - /bin/sh ${word 2,$^} ./cygdll.a "$(AS)" "$(AR)" $(NEW_FUNCTIONS) || exit 0 - (echo create $(LIB_NAME); echo addmod $(LIBCOS); echo addlib cygdll.a; echo save) | $(AR) -M - $(RANLIB) $@ +$(LIB_NAME): $(LIBCOS) | $(TEST_DLL_NAME) + ${srcdir}/mkimport ${toolopts} ${NEW_FUNCTIONS} $@ cygdll.a $^ ${STATIC_LIB_NAME}: mkstatic ${TEST_DLL_NAME} perl -d $< -x ${EXCLUDE_STATIC_OFILES} --library=${LIBC} --library=${LIBM} --ar=${AR} $@ cygwin.map @@ -442,22 +439,22 @@ shared.o: shared_info_magic.h $(srcdir)/devices.cc: gendevices devices.in devices.h ${wordlist 1,2,$^} $@ -${CURDIR}/libc.a: speclib ${LIB_NAME} ./libm.a libpthread.a libutil.a +${CURDIR}/libc.a: ${LIB_NAME} ./libm.a libpthread.a libutil.a ${speclib} -v ${@F} -${CURDIR}/libm.a: speclib ${LIB_NAME} $(LIBM) +${CURDIR}/libm.a: ${LIB_NAME} $(LIBM) ${speclib} ${@F} -libpthread.a: speclib ${LIB_NAME} pthread.o thread.o +libpthread.a: ${LIB_NAME} pthread.o thread.o ${speclib} ${@F} -libutil.a: speclib ${LIB_NAME} bsdlib.o +libutil.a: ${LIB_NAME} bsdlib.o ${speclib} ${@F} -libdl.a: speclib ${LIB_NAME} dlfcn.o +libdl.a: ${LIB_NAME} dlfcn.o ${speclib} ${@F} -libresolv.a: speclib ${LIB_NAME} minires.o +libresolv.a: ${LIB_NAME} minires.o ${speclib} ${@F} ${EXTRALIBS}: lib%.a: %.o 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 < newsym.dir/$newsym.s - - cat <> newsym.dir/$newsym.s - .section .idata\$7 - .long __head_cygwin1_dll - - .section .idata\$5 - .global __imp__$newsym -__imp__$newsym: .rva 1f - - .section .idata\$4 - .rva 1f - - .section .idata\$6 -1: .short 2 - .asciz "$oldsym" -EOF - $as -o newsym.dir/$newsym.o newsym.dir/$newsym.s -done -$ar crus $lib newsym.dir/*.o diff --git a/winsup/cygwin/rmsym b/winsup/cygwin/rmsym deleted file mode 100755 index 1549eed99..000000000 --- a/winsup/cygwin/rmsym +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/sh -lib=$1; shift -nm=$1; shift -ar=$1; shift -grepit=`echo $* | sed 's/ /\$|__imp__/g'` -[ -n "$grepit" ] && grepit="__imp__$grepit\$" -objs=`$nm $lib | awk -F: '/^d*[0-9][0-9]*.o:/ {obj=$1} '"/$grepit/"'{print obj}'` -[ -n "$objs" ] || exit 1 -$ar ds $lib $objs diff --git a/winsup/cygwin/speclib b/winsup/cygwin/speclib index b26644a1f..80ef23301 100755 --- a/winsup/cygwin/speclib +++ b/winsup/cygwin/speclib @@ -8,35 +8,35 @@ use strict; sub dllname($;$); my $static; -my $exclude; +my $inverse; +my @exclude; -GetOptions('static!'=>\$static, 'v|exclude!'=>\$exclude); +my ($ar, $as, $nm, $objcopy); +GetOptions('exclude=s'=>\@exclude, 'static!'=>\$static, 'v!'=>\$inverse, + 'ar=s'=>\$ar, 'as=s'=>\$as,'nm=s'=>\$nm, 'objcopy=s'=>\$objcopy); -my $nm = shift; -my $ar = shift; -my $libdll = File::Spec->rel2abs(shift @ARGV); -my $lib = File::Spec->rel2abs(pop @ARGV); +$_ = File::Spec->rel2abs($_) for @ARGV; -open my $nm_fd, '-|', $nm, '-Ap', '--defined-only', @ARGV, $libdll or +my $libdll = shift; +my $lib = pop; + +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/; while (<$nm_fd>) { 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; + 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;