RFC: Cygwin 64 bit?
Ryan Johnson
ryan.johnson@cs.utoronto.ca
Thu Aug 18 11:52:00 GMT 2011
On 18/08/2011 5:20 AM, Corinna Vinschen wrote:
> So, nobody except Earnie is interested in the way dlopen opens shared
> objects? Nobody even replied to the idea of the pseudo algorithm below.
> Does really nobody care?
The below looks fine to me, but I really didn't feel qualified to
comment. I had been lurking on this thread because I really don't know
much about the ins and outs of the Windows loader...
That said, it seemed from a different part of the thread that it should
be possible to wire in relative ../lib/ paths for dlls in such a way
that we'd no longer need to keep them in bin. It seems like that would
be a good avenue to pursue, because then the normal ../lib and ../lib64
conventions would solve the problem of a mixed 32/64-bit distribution
pretty nicely. Maybe we could even (gradually) move dlls out of /bin for
32-bit cygwin. The one thing that wasn't clear to me is what would
happen to apps which don't live in /usr/bin and which need to run
directly from windows, but I guess that problem already exists
regardless (mostly by moving all such apps into /usr/bin, e.g.
startxwin.exe).
If the above worked, then adding /usr/bin to the dlopen search path
would then be harmless but unnecessary. Or maybe I'm completely
misunderstanding things?
Thoughts?
Ryan
>
>
> Corinna
>
> On Aug 15 19:25, Corinna Vinschen wrote:
>> On Jul 3 11:21, Corinna Vinschen wrote:
>>> On Jul 2 22:52, Charles Wilson wrote:
>>>> Anyway, that's why I suggested that we add, now, a "fix" to cygwin64's
>>>> dlopen to 'substitute' dlopen("cyg64*") for requests to dlopen("cyg*")
>>> Good point.
>>>
>>> IMHO the order should be something like this:
>>>
>>> Is suffix ".so"?
>>> Yes -> Does the file exist?
>>> Yes -> Done
>>> No -> Replace ".so" with ".dll"
>>> #ifdef __X86_64__
>>> Does the filename start with "cyg"?
>>> Yes -> Replace "cyg" with "cyg64"
>>> Does the file exist?
>>> No -> Revert back to "cyg"
>>> #endif
>>> Does the filename start with "lib"?
>>> Yes -> Replace "lib" with "cyg"/"cyg64"
>>> Does the file exist?
>>> No -> Revert back to "lib"
>>> Does the file exist?
>>> Yes -> Done
>>> return ENOENT
>> I implemented the above algorithm for 32 bit Cygwin now, so DLLs are
>> searched for in dlopen using the above algorithm.
>>
>> The patch also changes the default search path. As before, it first
>> checks for LD_LIBRARY_PATH. However, given the fact that all shared
>> libs which are usually in /usr/lib on other systems, are in /usr/bin
>> on Cygwin, it makes a lot of sense to add /usr/bin to the search path.
>>
>> Is that something we should do now?
>>
>>
>> Corinna
>>
>> * dlfcn.cc (gfpod_helper): Helper function to search DLL using
>> a given DLL name. Change default search path to allow /usr/bin.
>> (get_full_path_of_dll): Find DLLs even if the caller used a ".so"
>> suffix or a "lib" prefix for the DLL.
>>
>> Index: dlfcn.cc
>> ===================================================================
>> RCS file: /cvs/src/src/winsup/cygwin/dlfcn.cc,v
>> retrieving revision 1.50
>> diff -u -p -r1.50 dlfcn.cc
>> --- dlfcn.cc 6 Jun 2011 05:02:09 -0000 1.50
>> +++ dlfcn.cc 15 Aug 2011 17:13:01 -0000
>> @@ -38,6 +38,18 @@ check_path_access (const char *mywinenv,
>>
>> /* Search LD_LIBRARY_PATH for dll, if it exists.
>> Return Windows version of given path. */
>> +static inline bool
>> +gfpod_helper (const char *name, path_conv&real_filename)
>> +{
>> + if (isabspath (name) ||
>> + (check_path_access ("LD_LIBRARY_PATH=", name, real_filename)
>> + ?: check_path_access ("/usr/bin:/usr/lib", name, real_filename)) == NULL)
>> + real_filename.check (name, PC_SYM_FOLLOW | PC_NULLEMPTY);
>> + if (!real_filename.exists ())
>> + real_filename.error = ENOENT;
>> + return !real_filename.error;
>> +}
>> +
>> static bool __stdcall
>> get_full_path_of_dll (const char* str, path_conv&real_filename)
>> {
>> @@ -55,12 +67,33 @@ get_full_path_of_dll (const char* str, p
>>
>> strcpy (name, str); /* Put it somewhere where we can manipulate it. */
>>
>> - if (isabspath (name) ||
>> - (check_path_access ("LD_LIBRARY_PATH=", name, real_filename)
>> - ?: check_path_access ("/usr/lib", name, real_filename)) == NULL)
>> - real_filename.check (name, PC_SYM_FOLLOW | PC_NOFULL | PC_NULLEMPTY);
>> + char *basename = strrchr (name, '/');
>> + basename = basename ? basename + 1 : name;
>> + char *suffix = strrchr (name, '.');
>> + if (suffix&& suffix< basename)
>> + suffix = NULL;
>>
>> - if (!real_filename.error)
>> + /* Is suffix ".so"? */
>> + if (suffix&& !strcmp (suffix, ".so"))
>> + {
>> + /* Does the file exist? */
>> + if (gfpod_helper (name, real_filename))
>> + return true;
>> + /* No, replace ".so" with ".dll". */
>> + strcpy (suffix, ".dll");
>> + }
>> + /* Does the filename start with "lib"? */
>> + if (!strncmp (basename, "lib", 3))
>> + {
>> + /* Yes, replace "lib" with "cyg". */
>> + strncpy (basename, "cyg", 3);
>> + /* Does the file exist? */
>> + if (gfpod_helper (name, real_filename))
>> + return true;
>> + /* No, revert back to "lib". */
>> + strncpy (basename, "lib", 3);
>> + }
>> + if (gfpod_helper (name, real_filename))
>> return true;
>>
>> set_errno (real_filename.error);
>>
>> --
>> Corinna Vinschen Please, send mails regarding Cygwin to
>> Cygwin Project Co-Leader cygwin AT cygwin DOT com
>> Red Hat
More information about the Cygwin-developers
mailing list