This is the mail archive of the cygwin mailing list for the Cygwin project.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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

[ I switched from cygwin-apps, where it is not appropriate ]

Charles Wilson schrieb:
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
-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?

Many thanks for this explanation. I was wrong.

Yes, indeed.
People forget about -no-undefined in their,
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".

True. 99% of all conflicts are just incorrect object and library order. Seldom they miss a .o, lib or add a wrong dependency.


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

Don't do that.

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?

You caught me. Indeed.

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
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.)

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.

:) If nobody wants it, I will not write such a hack. Rebuilding the DLL is easier.

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.

Thanksfully the section headers are protected by two checksums (and even more magic), so nobody can hexedit the DLL name :)
I knew that there must be an explanation, but I couldn't find it.

So it would only fix the perl problem, but for perl alone it will be MUCH easier to provide a package update. Agreed.
And no package so far uses a embedded shared perl interpreter, to my knowledge. Just postgresql starting with v8.0, for v7.x it is broke). That are my primary concerns, because I just want to take over from Jason.

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/" might be "c:/cygwin/lib/". 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.

You got me wrong. My "/usr/lib/" up there is of course a binary DLL (Ix86 COFF with PE), with just a funny filename.
In my experience LoadLibrary (dlopen) will load any filename ending with any extension, as long as it is a true DLL - relocatable Ix86 COFF with PE and some more restrictions. (PEI is just the win32 version, an old header prepended, printing the "This program cannot be run in DOS mode" warning. I believe.)
As long as you provide the basename+extension. path not necessary. basename is not enough (Default: ".DLL"). Hell, Windows even thinks that the extension of "perl5.8.1.dll" is "8.1.dll", and not "dll". But this may vary, depending on the library function used internally.

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...

I believe it was developed by the WINE folks, because MSVC suddenly supported lazy loading (requested by some folks, like Autodesk) and the WINE folks had to load these beasts. gcc-core (or just binutils?) picked it up lately, but I don't think the decided on the ld switch naming yet. I don't follow these lists, just the ChangeLog.
ld --help |grep delay
ld --help |grep lazy

It is just an early idea, but I don't think a bad one.
And there's no hurry: I don't want to replace it. Just talk about it.
If would make sense.

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.

Where? (just a rough substring would be enough to google it)
I couldn't find it anywhere. Most of the things I found at WINE, and know from my former MSVC + AutoCAD + FFI days, where Autodesk developed its own DLL loading + extension scheme, just to support C++ class extensions and overloading by external DLL's. Which I hacked and extended for lisp.

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.
Reini Urban

Unsubscribe info:
Problem reports:

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]