How can you change the DLL name in the .idata section header of a DLL?

Charles Wilson cygwin@cwilson.fastmail.fm
Wed Sep 29 22:13:00 GMT 2004


Reini Urban wrote:

> Spoofing is a good point.
> But I might prefer to be able to update dynamic dependencies without 
> breakage. openssl usually gets updated with an security issue.
> e.g curl or postgresql cannot deal with an openssl update which deletes 
> cygssl-0.9.7.dll and replaces that with cygssl-0.9.8.dll.
> If we had just a cygssl.dll we can simply upgrade that and nothing breaks.

That's the way most other DLLs on cygwin are named.  But cygssl is 
different -- as a security/encryption DLL, considerations other that 
"ease of slipstream replacement" are more important.  Usually there is a 
reason when a maintainer chooses to go against the common practice: 
openssl is one of those.

> Anyway, see cygperl.dll:
> DLL api's should stay binary compatible IMHO, unless it's really an 
> issue (such as int32 => int64 on cygwin's switch from 1.3 => 1.5).
> You normally can trust MS DLL backwards compatibility. Newer features 
> are just added, or new versioned DLL's appear - newlib2.dll - but old 
> DLL's must stay. ("contract")
> With our libtool generated DLL names I'm not that happy.

Perl's build system is a nightmare.  We're lucky we have a shared 
version at all.  But if you want to assist Geritt in fixing some of the 
warts in the perl build system, I'm sure he'd welcome patches (and, as I 
indicate below, concentrating on the ACTUAL problems rather than trying 
to wholesale rework libtool/binutils/gcc/etc is probably a quicker path 
to solving your issues).

That name (cygssl-0.9.7.dll) is not libtool's fault.  Libtool uses two 
different mechanisms for setting the name of a DLL:
   -version-info c:r:a
and
   -release x.y.z
There are explicit rules governing how c, r, and a are to be updated, 
and how the dll name is derived from c,r,a in order to insure that (a) 
the library name changes rarely, and only when necessary to indicate 
binary incompatibility, and (b) all dlls with the same name are 
backwards compatible (e.g. old exe's linked against the old DLL will 
still work with the new DLL).  The libtool maintainers STRONGLY suggest 
using the -version-info paradigm.  On cygwin, this results in library 
names like libintl-3.dll (NOT libintl-0.12.1.dll)   Most cygwin packages 
which provide DLLs obey these rules and follow this "suggestion".

But the libtool folks do provide the -release mechanism, which is often 
used to name the DLL using the major.minor.micro revision numbering 
system.  There are sometimes good reasons to do this, but usually it's 
because the package maintainer doesn't understand library versioning, or 
libtool.  cygssl behave this way (even though it doesn't use libtool IIRC).

If libtool names were used "correctly" by the packages, then you would 
be "happy" -- and further, on cygwin we take GREAT PAINS to ensure that 
compatibility DLLs are kept around virtually forever whenever DLL names 
do change.  So what, exactly, is your beef?  Just perl and ssl -- and 
THAT justifies reworking libtool and binutils, and rewriting the 
underlying conventions of DLL names and cygwin's runtime loader?

> Yes, indeed.
> People forget about -no-undefined in their Makefile.am,
> and then on any conflict libtool generates only the static version.
> Which was e.g. the case with having -lgdi32 in the dependencies, for 
> which no syms could be found.

It seems that the problem is NOT, then, libtool or the 
existence/non-existence of a .la file.  The problem is the "conflict" 
(e.g. build errors in the package in question).  Focus your efforts on 
fixing the problem, not band-aiding a "solution".

> ------------------------------
> 
> BTW, a binutils question:
> "How can you change the DLL name in the .idata section header of a DLL?"

Don't do that.

> Rationale:
> DLL's cannot by symlinked on cygwin, unlike on other platforms.
> DLL names are usually quite version specific, which makes perfect sense 
> on those other platforms. DLL names are built in the executable PE 
> header, so on any DLL rename or upgrade, breakage will occur. On MS 
> Win32 old DLL's just stay, so no breakage will occur.
> Not so with the cygwin setup.exe.

Faulty.  DLLs don't often change names, and when they do, the old 
versions stay around.  If not, then THAT is the problem.

For instance, how many versions of libintl*.dll do you have on your 
system?  libncurses*.dll?  cygtiff*.dll?  cygjpeg*.dll?  cyggdbm*.dll? 
cygdb*.dll?

Are you noticing a pattern yet?

It appears that your biggest beef is with the cygssl (and perl) DLL 
naming scheme: it uses -release versioning (even tho it actually doesn't 
use libtool to do it, IIRC).  (perl does something even wierder; I'm not 
going there).

This presents a difficulty for packages which depend on cygssl*dll. 
However, this IS one of those times when there is a good reason to 
change the DLL name on every security fix (e.g. micro release version). 
    It means you can't silently slip an SSL bugfix into an older version 
of imapd, but you also can't silently slip in NEW SLL security holes 
possibly introduced by the new library.

Each dependent app can make its own determination that "Yes, the bugfix 
in version+1 outweighs the risk of new bugs, so I will now recompile 
against the latest version".

Downside: on our platform, at present, it appears that "older" versions 
of cygssl*.dll are not retained, because the "openssl" package is not 
"split" into independent "library" and "other" packages: e.g.
    libssl0_9_7 package contains /bin/cygssl-0.9.7.dll
    libssl0_9_8 package contains /bin/cygssl-0.9.8.dll
while
    openssl     package contains every thing else.
That is a maintainer issue, and I'm sure there is a good reason (perhaps 
the openssl package itself is not amenable to this splitup.  For 
instance, suppose that the "everything else" is version-specific, yet 
lives in /usr/share/openssl/.  You'd need multiple versions of 
"everything else" but they all want to own the same directory.  Problems.)

> Solution:
> Use as much generic dll names as possible (such as cygperl58.dll, 
> cygssl-1.dll, ...).

But that IS what we do, *whenever* possible.  When we (cygwin pkg 
maintainers) don't, there is usually a good reason.  One which, quite 
frankly, you obviously haven't done enough research to identify == 
because you're focusing on libtool and binutils issues, when it appears 
the difficulties are much more localized to the specifics of a few 
packages like openssl and perl.

> Provide an objdump option to rename a certain DLL path to fix breakage 
> for older libs, until they get rebuilt.

God no.  If anyone ever does such a thing to any of the DLLs supplied by 
my packages, and then comes complaining to the cygwin list because "tiff 
doesn't work anymore" not only will I not support their bastardization, 
but I will drop the tiff package from the distro like a bad habit.

I do NOT have enough time to support people who take a hexeditor to the 
internals of the packages I supply.  Use them as is, or don't use them 
at all.

> One could also hardcode the DLL path to some /usr/lib; /usr/libexec, 
> /usr/<package>/lib, so that we can rid of /usr/bin cyg*.dll pollution. 
> But this will only work if the cygwin mount will not change. The windows 
> process loader needs the windows path. So "/usr/lib/cygperl.so" might be 
> "c:/cygwin/lib/cygperl.so". No major problem if objcopy will support 
> that. Something like rebaseall.

The windows loader will only load .dlls (and .ax but that's a special 
case for the COM+ architecture AFAIK).  And .dlls follow certain rules. 
  It will not load .so's even if the .so contains pei-386 code.  You 
need a special loader to do this instead; something like libltdl would 
have to be built into cygwin1.dll -- but it wouldn't be exactly libltdl 
for, I hope, obvious reasons.

> Another idea is to make those .idata sections weak and provide a hook to 
> go over cygpath resolution via libltdl. If that will work.
> Weak is rather new I suppose, and I haven't looked at the implementation 
> of lazy linking with ld.

Hell, I don't even know if weak WORKS on cygwin; it was developed over 
in the mingw arena; as far as I know they didn't even test it on our 
side of the fence.  And you want to replace the shared library mechanism 
with it?  Walk before you run...

All of these ideas (like using a cygwin runtime loader instead of 
relying on DLLs and the Windows Runtime Loader) have been brought up 
before.  But nobody has demonstrated any working code, nor demonstrated 
1/10th the amount of thought necessary to forestall the problems 
inherent in those plans.  Show me the code.

Look, I know this message (and my last) have been snippy.  I'm sorry for 
that, but about every three months somebody comes along with a great 
idea to "fix" a problem with DLLs on cygwin.  (Usually -- although not 
in your case -- the problem is actually between the keyboard and the 
chair)  They almost never demonstrate a thorough understanding of the 
issues surrounding dynamic libraries, naming schemes, the Windows 
Loader.  Further, they often approach the current paradigms with faulty 
assumptions (e.g. cygwin DLL names change often; they don't;  DLLs are 
removed by setup willy-nilly; they aren't [current problems with 
cygwin1.dll+setup notwithstanding]) nor do they understand the reasons 
things are done as they are presently.

So please, before you continue on this path, go back to the earlist 
cygwin-apps archives, and read...then, read it again.  We HAVE thought 
about these issues.

--
Chuck



More information about the Cygwin-apps mailing list