This is the mail archive of the
cygwin-apps@cygwin.com
mailing list for the Cygwin project.
RE: cygwin ld import library issue fix (removing unused "_nm_" symbols)
- From: "Ralf Habacker" <Ralf dot Habacker at freenet dot de>
- To: "Charles Wilson" <cwilson at ece dot gatech dot edu>
- Cc: "Kde-Cygwin" <kde-cygwin at kde dot org>,"Cygwin-Apps" <cygwin-apps at cygwin dot com>,"Binutils" <binutils at sources dot redhat dot com>
- Date: Sat, 27 Apr 2002 18:41:15 +0200
- Subject: RE: cygwin ld import library issue fix (removing unused "_nm_" symbols)
> In theory, it looks good. However, have you tested the following:
>
> a) build a dll using an unmodified ld.
ls /usr/i686-pc-cygwin/bin/ -l
lrwxrwxrwx 1 1002 Kein 26 Apr 19 07:49 ar.exe ->
/usr/bin/ar.exe
lrwxrwxrwx 1 1002 Kein 26 Apr 19 07:49 as.exe ->
/usr/bin/as.exe
lrwxrwxrwx 1 1002 Kein 26 Apr 19 07:49 ld.exe ->
/usr/bin/ld.exe
lrwxrwxrwx 1 1002 Kein 26 Apr 19 07:49 nm.exe ->
/usr/bin/nm.exe
lrwxrwxrwx 1 1002 Kein 30 Apr 19 07:49 ranlib.exe ->
/usr/bin/ranlib.exe
lrwxrwxrwx 1 1002 Kein 29 Apr 19 07:49 strip.exe ->
/usr/bin/strip.exe
$ cp /bin/ld.exe.20011116 /bin/ld.exe
$ ld -v --help | head -1
GNU ld version 2.11.92 20011216
------------------------------------------------
$ cat dll.cc
------------------------------------------------
#include <stdio.h>
int var0000=0;
namespace A {
void printfunc0000(void){ printf("printfunc%04d called\n",0); }
}
------------------------------------------------
$ cat dll.h
------------------------------------------------
extern int var0000;
namespace A {
void printfunc0000(void);
}
#define vars() \
printf("v0000=%04d\n",var0000);\
#define funcs() \
A::printfunc0000();\
------------------------------------------------
$ make dll.dll
gawk -f dll.awk >dll.cc
g++ -c -o dll.o dll.cc
g++ --shared dll.o -o dll.dll -Wl,--out-implib,libdll.a
Creating library file: libdll.a
$ nm libdll.a
d000011.o:
00000000 i .idata$4
00000000 i .idata$5
00000000 i .idata$7
00000000 I _dll_dll_iname
d000000.o:
00000000 i .idata$2
00000000 i .idata$4
00000000 i .idata$5
00000000 I __head_dll_dll
U _dll_dll_iname
d000010.o:
00000000 i .idata$4
00000000 i .idata$5
00000000 i .idata$6
00000000 i .idata$7
00000000 t .text
U __head_dll_dll
00000000 I __imp__var0000
00000000 I __nm__var0000
d000009.o:
00000000 i .idata$4
00000000 i .idata$5
00000000 i .idata$6
00000000 i .idata$7
00000000 t .text
U __head_dll_dll
00000000 I __imp__printfunc0000__1Av
00000000 I __nm__printfunc0000__1Av
00000000 T _printfunc0000__1Av
d000008.o:
00000000 i .idata$4
00000000 i .idata$5
00000000 i .idata$6
00000000 i .idata$7
00000000 t .text
U __head_dll_dll
00000000 I __imp___nm__realloc
00000000 I __nm___nm__realloc
d000007.o:
00000000 i .idata$4
00000000 i .idata$5
00000000 i .idata$6
00000000 i .idata$7
00000000 t .text
U __head_dll_dll
00000000 I __imp___nm__printf
00000000 I __nm___nm__printf
d000006.o:
00000000 i .idata$4
00000000 i .idata$5
00000000 i .idata$6
00000000 i .idata$7
00000000 t .text
U __head_dll_dll
00000000 I __imp___nm__malloc
00000000 I __nm___nm__malloc
d000005.o:
00000000 i .idata$4
00000000 i .idata$5
00000000 i .idata$6
00000000 i .idata$7
00000000 t .text
U __head_dll_dll
00000000 I __imp___nm__free
00000000 I __nm___nm__free
d000004.o:
00000000 i .idata$4
00000000 i .idata$5
00000000 i .idata$6
00000000 i .idata$7
00000000 t .text
U __head_dll_dll
00000000 I __imp___nm__dll_dllcrt0
00000000 I __nm___nm__dll_dllcrt0
d000003.o:
00000000 i .idata$4
00000000 i .idata$5
00000000 i .idata$6
00000000 i .idata$7
00000000 t .text
U __head_dll_dll
00000000 I __imp___nm__cygwin_internal
00000000 I __nm___nm__cygwin_internal
d000002.o:
00000000 i .idata$4
00000000 i .idata$5
00000000 i .idata$6
00000000 i .idata$7
00000000 t .text
U __head_dll_dll
00000000 I __imp___nm__cygwin_detach_dll
00000000 I __nm___nm__cygwin_detach_dll
d000001.o:
00000000 i .idata$4
00000000 i .idata$5
00000000 i .idata$6
00000000 i .idata$7
00000000 t .text
U __head_dll_dll
00000000 I __imp___nm__calloc
00000000 I __nm___nm__calloc
done
> b) build an app that uses that dll, and which accesses both a function
> export and a data export from the dll.
------------------------------------------------
$ cat client.cc
------------------------------------------------
#include <stdio.h>
#include "dll.h"
main()
{
funcs();
vars();
}
------------------------------------------------
$ make client.exe
g++ -c -o client.o client.cc
g++ -o client.exe client.o -v -Wl,--enable-auto-import -L. -ldll
Warning: resolving _var0000 by linking to __imp__var0000 (auto-import)
$ ./client.exe
printfunc0000 called
v0000=0000
> c) rebuild the dll using your modified ld.
cp ~/src/sources.redhat.com/src/ld/ld-new /bin/ld.exe
$ ld -v --help | head -1
GNU ld version 2.12.90 20020425
$ rm dll.dll
habacker@BRAMSCHE ~/src/ld-contrib/ld-bugfix-test
$ make dll.dll
g++ --shared dll.o -o dll.dll -Wl,--out-implib,libdll.a
Creating library file: libdll.a
to verify that the patch does his work, compare with mentioned above nm list.
$ nm libdll.a
d000003.o:
00000000 i .idata$4
00000000 i .idata$5
00000000 i .idata$7
00000000 I _dll_dll_iname
d000000.o:
00000000 i .idata$2
00000000 i .idata$4
00000000 i .idata$5
00000000 I __head_dll_dll
U _dll_dll_iname
d000002.o:
00000000 i .idata$4
00000000 i .idata$5
00000000 i .idata$6
00000000 i .idata$7
00000000 t .text
U __head_dll_dll
00000000 I __imp__var0000
00000000 I __nm__var0000
d000001.o:
00000000 i .idata$4
00000000 i .idata$5
00000000 i .idata$6
00000000 i .idata$7
00000000 t .text
U __head_dll_dll
00000000 I __imp__printfunc0000__1Av
00000000 T _printfunc0000__1Av
> d) does the app still work, without relinking?
$ ./client
printfunc0000 called
v0000=0000
e) additional relink app with unmodified ld to see if old ld can handle this
import library
$ cp /bin/ld.exe.2001_10_03 /bin/ld.exe
$ rm client.exe
$ make client.exe
g++ -c -o client.o client.cc
g++ -o client.exe client.o -v -Wl,--enable-auto-import -L. -ldll
Warning: resolving _var0000 by linking to __imp__var0000 (auto-import)
$ ./client.exe
printfunc0000 called
v0000=0000
So this seems to work.
Regards
Ralf