speclib vs. -lc trouble.

Dave Korn dave.korn.cygwin@googlemail.com
Thu Apr 9 15:20:00 GMT 2009

    Hi guys,

  I've been back over this as promised and figured out what went wrong, and
it's easily enough fixed.  It's not a bug per se in dlltool, just that it's a
little surprised to find itself being driven in this way and it needs a
helping hand to get it right.

  I went back to the test EXEs linked with and without -lc, and examined the
import sections in detail.  In fact, they are both syntactically well-formed
and complete, there's no overlap or trashing going on.  But there is a
difference: in the failing EXE, the ordinal/hint values in the import lookup
table entries are wrong.  As an example, I tracked what was happening to the
import of 'abort()'

--- lc.txt	2009-04-09 14:13:01.921875000 +0100
+++ nolc.txt	2009-04-09 14:13:05.375000000 +0100
@@ -2,113 +2,106 @@ Microsoft (R) COFF Binary File Dumper Ve
 Copyright (C) Microsoft Corp 1992-1998. All rights reserved.

-Dump of file ld1
+Dump of file ld1-nolc


   Section contains the following imports:

-                549210 Import Address Table
-                54907C Import Name Table
+                54921C Import Address Table
+                549068 Import Name Table
                      0 time date stamp
                      0 Index of first forwarder reference
        [ . . . ]
-                 26D  abort
        [ . . . ]
-    cygwin1.dll
-                549358 Import Address Table
-                5491C4 Import Name Table
-                     0 time date stamp
-                     0 Index of first forwarder reference
        [ . . . ]
+                 292  abort

  'ld1' is the failing EXE, 'ld1-nolc' works correctly, and sure enough, 292
is the correct hint for abort() in cygwin1.dll's export table.  I looked in
the export libs, extracting the objects with the import entries for abort(),
and verified that the different ordinals were recorded there:

--- lcyg-obj.txt	2009-04-09 14:48:32.390625000 +0100
+++ lc-obj.txt	2009-04-09 14:48:04.046875000 +0100
@@ -1,6 +1,6 @@

-d000659.o:     file format pe-i386
+diads00621.o:     file format pe-i386

 Contents of section .idata$6:
- 0000 92026162 6f727400                    ..abort.
+ 0000 6d026162 6f727400

  The problem comes from the mode of operation of dlltool in speclib.  dlltool
expects to be given a bunch of objects and a def file for exports and to build
a dll with an export section and an import library.  In the speclib usage,
we're just feeding it a def file (through stdin) and asking it to output an
import library.

  The thing is, because dlltool expects to be generating dll and library
together, it creates hint ordinals for all the exports based on what it sees
in the def file, numbering them incrementally[*]; and then because we're not
generating a DLL to match, and because the def file we're feeding it has been
filtered from the one that was actually used when generating the DLL, the
export ordinals get out of sync with the actual ones from the DLL.

  There are a number of nice ways we could fix this upstream, it would be nice
to teach dlltool (and/or ld) to read an existing dll and create a def file and
import lib using the information from the dll.

  Locally, we could adjust speclib; where it generates the new filtered def
file contents for libc.a, it could look up the ordinals for the imports in the
existing dll and generate the def file syntax that specifies ordinals
explicitly by value.

  One robust way to do that would be to just hack gendef to explicitly
generate ordinals for everything in the first place, my perl-fu isn't up to
much but it looks to me like speclib should be able to pass them straight
through with just a little tweaking.


[*] See mangle_defs() in dlltool.c:

  /* Fill exp entries with their hint values.  */
  for (i = 0; i < d_nfuncs; i++)
    if (!d_exports_lexically[i]->noname || show_allnames)
      d_exports_lexically[i]->hint = hint++;

More information about the Cygwin-developers mailing list