[SOLVED] Re: under cygwin, zsh cannot run when built against ncurses9-5.7-13

Dave Korn dave.korn.cygwin@googlemail.com
Wed Mar 25 13:03:00 GMT 2009


[SOLVED, yes, but no patch just yet, only the full explanation.]

Corinna Vinschen wrote:

> What I'm wondering is, why did it work all these years before?  Is it
> a bug in the new binutils?  Or was it a bug in the old binutils to
> create working results?


  I installed Cygwin-1.5 from the Time Machine, circa 2006/07/25/023017, and
rebuilt zsh from source.  Big thanks to Peter A. Castro for the CTM.

  It all came out valid, despite showing the same behaviour with -lm.  Here's
the diff between the verbose linker output caused by linking the libzsh DLL
without or with '-lm':

 GNU ld version 2.17.50 20060709
 GNU ld version 2.17.50 20060709
   Supported emulations:
@@ -295,6 +295,11 @@ attempt to open /usr/lib/libcurses.dll.a
 (/usr/lib/libcurses.dll.a)d000404.o
 (/usr/lib/libcurses.dll.a)d000000.o
 (/usr/lib/libcurses.dll.a)d000479.o
+attempt to open /usr/lib/libm.dll.a failed
+attempt to open /usr/lib/m.dll.a failed
+attempt to open /usr/lib/libm.a succeeded
+(/usr/lib/libm.a)d001177.o
+(/usr/lib/libm.a)d000000.o
 attempt to open /usr/lib/libgcc.dll.a failed
 attempt to open /usr/lib/gcc.dll.a failed
 attempt to open /usr/lib/libgcc.a failed
@@ -420,7 +425,6 @@ attempt to open /usr/lib/libcygwin.a suc
 (/usr/lib/libcygwin.a)d001399.o
 (/usr/lib/libcygwin.a)d001401.o
 (/usr/lib/libcygwin.a)d000959.o
-(/usr/lib/libcygwin.a)d001177.o
 (/usr/lib/libcygwin.a)d001477.o
 (/usr/lib/libcygwin.a)setgid.o
 (/usr/lib/libcygwin.a)setuid.o

  As you see, it's showing the same behaviour as the latest version does: it
pulls in partial import table entries from libm, leaving an uncapped IAT.  But
it works in this case, because looking at the overall linker output:

attempt to open /usr/lib/libm.dll.a failed
attempt to open /usr/lib/m.dll.a failed
attempt to open /usr/lib/libm.a succeeded
(/usr/lib/libm.a)d001177.o
(/usr/lib/libm.a)d000000.o
attempt to open /usr/lib/libgcc.dll.a failed
attempt to open /usr/lib/gcc.dll.a failed
attempt to open /usr/lib/libgcc.a failed
attempt to open /usr/lib/gcc.lib failed
attempt to open /usr/lib/cyggcc.dll failed
attempt to open /usr/lib/libgcc.dll failed
attempt to open /usr/lib/gcc.dll failed
attempt to open /usr/lib/libgcc.a failed
attempt to open /usr/lib/gcc/i686-pc-cygwin/3.4.4/libgcc.dll.a failed
attempt to open /usr/lib/gcc/i686-pc-cygwin/3.4.4/gcc.dll.a failed
attempt to open /usr/lib/gcc/i686-pc-cygwin/3.4.4/libgcc.a succeeded
(/usr/lib/gcc/i686-pc-cygwin/3.4.4/libgcc.a)_chkstk.o
(/usr/lib/gcc/i686-pc-cygwin/3.4.4/libgcc.a)_divdi3.o
(/usr/lib/gcc/i686-pc-cygwin/3.4.4/libgcc.a)_moddi3.o
(/usr/lib/gcc/i686-pc-cygwin/3.4.4/libgcc.a)_udivdi3.o
(/usr/lib/gcc/i686-pc-cygwin/3.4.4/libgcc.a)_umoddi3.o
attempt to open /usr/lib/libcygwin.dll.a failed
attempt to open /usr/lib/cygwin.dll.a failed
attempt to open /usr/lib/libcygwin.a succeeded
(/usr/lib/libcygwin.a)dll_entry.o

... the next thing that adds any entries into the import sections is libcygwin
itself, so the two tables simply merge into one correctly topped-and-tailed
one.  The entries linked in from static libgcc only add to the text and data
sections, and so the import section entries from libm and libcygwin
concatenate perfectly.

  On newer systems with gcc-4 and shared libgcc, that all changes:

attempt to open /usr/lib/libm.dll.a failed
attempt to open /usr/lib/m.dll.a failed
attempt to open /usr/lib/libm.a succeeded
(/usr/lib/libm.a)d001286.o
(/usr/lib/libm.a)d000000.o
attempt to open /usr/lib/libgcc_s.dll.a failed
attempt to open /usr/lib/gcc_s.dll.a failed
attempt to open /usr/lib/libgcc_s.a failed
attempt to open /usr/lib/gcc_s.lib failed
attempt to open /usr/lib/cyggcc_s.dll failed
attempt to open /usr/lib/libgcc_s.dll failed
attempt to open /usr/lib/gcc_s.dll failed
attempt to open /usr/lib/libgcc_s.a failed
attempt to open /usr/lib/gcc/i686-pc-cygwin/4.3.2/libgcc_s.dll.a succeeded
(/usr/lib/gcc/i686-pc-cygwin/4.3.2/libgcc_s.dll.a)d000038.o
(/usr/lib/gcc/i686-pc-cygwin/4.3.2/libgcc_s.dll.a)_chkstk.o
(/usr/lib/gcc/i686-pc-cygwin/4.3.2/libgcc_s.dll.a)d000072.o
(/usr/lib/gcc/i686-pc-cygwin/4.3.2/libgcc_s.dll.a)d000100.o
(/usr/lib/gcc/i686-pc-cygwin/4.3.2/libgcc_s.dll.a)d000102.o
(/usr/lib/gcc/i686-pc-cygwin/4.3.2/libgcc_s.dll.a)d000000.o
(/usr/lib/gcc/i686-pc-cygwin/4.3.2/libgcc_s.dll.a)d000104.o
attempt to open /usr/lib/libcygwin.dll.a failed
attempt to open /usr/lib/cygwin.dll.a failed
attempt to open /usr/lib/libcygwin.a succeeded
(/usr/lib/libcygwin.a)dll_entry.o
(/usr/lib/libcygwin.a)d000731.o

  Now that libgcc is a DLL, it *does* add import section entries (as well as
code/data), and so we end up with the libgcc import table in between the libm
entries carrying the head of the cygwin1.dll import table and the libcygwin
entries containing the tail; it's effectively embedded in the middle of it.
This has all the expected bad results.

  So the linker is DTRT, the problem has always existed but been masked by the
fact that nothing between -lm and -lcygwin used to import anything, the
problem has arisen now because now that does happen, and the solution is to
mung the symbols in the import top/tail sections in libm so that libm and
libcygwin both each add a complete import table entry of their own (there's no
problem having two import tables against the same DLL).  Once I've figured out
how that perl script works, I'll be able to suggest a patch.

    cheers,
      DaveK



--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Problem reports:       http://cygwin.com/problems.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/



More information about the Cygwin mailing list