Jump to page: 1 2
Thread overview
[Issue 15060] Can't load a D shared library first, then load a C shared library
Sep 16, 2015
ponce
Sep 16, 2015
ponce
Sep 18, 2015
ponce
Sep 19, 2015
Martin Nowak
Sep 27, 2015
ponce
Sep 28, 2015
bitwise
Sep 28, 2015
Jacob Carlborg
Sep 28, 2015
bitwise
Oct 01, 2015
ponce
Oct 01, 2015
Jacob Carlborg
Oct 01, 2015
ponce
Oct 02, 2015
bitwise
Oct 02, 2015
Jacob Carlborg
Oct 02, 2015
bitwise
Oct 02, 2015
bitwise
Dec 17, 2022
Iain Buclaw
September 16, 2015
https://issues.dlang.org/show_bug.cgi?id=15060

--- Comment #1 from ponce <aliloko@gmail.com> ---
Suggestion from David Nadlinger

"
This is OS X only, right? In this case, it is hard to judge where exactly it
sits and what needs to be done to fix it, as no work has been done on dylib
support recently in either compiler. A wild guess is that there might still be
an image change handler, etc. registered that dyld tries to call when loading
the new library, but which no longer exists in the program. Searching druntime
for "_dyld" might reveal something of this sort."

--
September 16, 2015
https://issues.dlang.org/show_bug.cgi?id=15060

--- Comment #2 from ponce <aliloko@gmail.com> ---
I found a 2012 conversation here that talks about this very problem: https://github.com/D-Programming-Language/druntime/pull/228

--
September 18, 2015
https://issues.dlang.org/show_bug.cgi?id=15060

--- Comment #3 from ponce <aliloko@gmail.com> ---
Hacky workaround found by bitwise and Martin Nowak: http://forum.dlang.org/post/lldikuutgrpmmyuhfukr@forum.dlang.org

--
September 19, 2015
https://issues.dlang.org/show_bug.cgi?id=15060

Martin Nowak <code@dawg.eu> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |code@dawg.eu

--- Comment #4 from Martin Nowak <code@dawg.eu> ---
Can someone please try to fix this properly in druntime?
If it's not doable using the dyld API, I might work on adding init/fini calls
to any OSX binary (similar to what we do on ELF).

--
September 27, 2015
https://issues.dlang.org/show_bug.cgi?id=15060

--- Comment #5 from ponce <aliloko@gmail.com> ---
Unfortunately I'm trying to bootstrap a business so I'll live with the hacky
work-around and move on to the next task (I do everything).
It's also way beyond my understanding.

I've bountied $50 on the equivalent bug in LDC, this isn't much, so if someone want to do this, quote your price here (I would move the bounty on the proper bug but not sure how to do it).

https://github.com/ldc-developers/ldc/issues/1071 https://www.bountysource.com/issues/26587024-can-t-load-a-d-shared-library-first-then-load-a-c-shared-library

--
September 28, 2015
https://issues.dlang.org/show_bug.cgi?id=15060

bitwise <nicolas.jinchereau@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |nicolas.jinchereau@gmail.co
                   |                            |m

--- Comment #6 from bitwise <nicolas.jinchereau@gmail.com> ---
For reference:

dyld's source:

http://www.opensource.apple.com/source/dyld/ http://www.opensource.apple.com/source/dyld/dyld-353.2.3/

The callbacks being discussed:
'_dyld_register_func_for_add_image'
'_dyld_register_func_for_remove_image'
https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man3/dyld.3.html
https://developer.apple.com/library/mac/documentation/DeveloperTools/Reference/MachOReference/index.html

'dyld_register_image_state_change_handler'
couldn't find docs, but declaration/definition are here:
http://www.opensource.apple.com/source/dyld/dyld-353.2.3/include/mach-o/dyld_priv.h
http://www.opensource.apple.com/source/dyld/dyld-353.2.3/src/dyldAPIs.cpp

Finally, I don't see any callback API which allows you to unregister the "library loaded" callback, so I think that adding init/fini calls is the solution.

Now, when the library is loaded, and init/fini are called, we need a way to get the mach_header* for the library which is loading. 'dladdr' can do this. It's documented that the 'dli_fbase' member of dl_info is a (mach_header*). So a private symbol can be added to the files along with the init/fini calls...or I suppose you could use the address of the init/fini calls themselves.. and pass the symbol to dladdr.

https://developer.apple.com/library/mac/documentation/DeveloperTools/Reference/MachOReference/index.html#//apple_ref/c/func/dladdr

The other piece of information that you need is the vmaddr_slide value. Right now, '_dyld_get_image_slide' is listed in 'dyld_priv.h'. If it turns out that _dyld_get_image_slide is a private API or something, and not allowed in the Apple Store, we can use plan B, which is to just iterate the mach_images and vmaddr_slides in lockstep until a match is found using these APIs:

uint32_t _dyld_image_count()
const struct mach_header* _dyld_get_image_header(uint32_t image_index)
intptr_t _dyld_get_image_vmaddr_slide(uint32_t image_index)

These three are APIs are here: https://developer.apple.com/library/mac/documentation/DeveloperTools/Reference/MachOReference/index.html

'_dyld_get_image_slide' can be found here: http://www.opensource.apple.com/source/dyld/dyld-353.2.3/include/mach-o/dyld_priv.h


Last time I looked, it seemed like this is more complicated than what you've done for ELF. I think manually injecting this code in the backend as ASM would be very difficult. I would(if I knew how) instead try to add some pragmas to DMD to help out, so that init/fini could just be written in D. Then, DMD's front end could inject the needed code.

For example, LDC already has these, so maybe DMD could too:

pragma(LDC_global_crt_ctor, 1024)
pragma(LDC_global_crt_dtor, 1024)
http://wiki.dlang.org/LDC-specific_language_changes

I think one more could make symbols private(GCC has something like this)
pragma(visibility, hidden)

Since public symbols are merged even between shared libraries on OSX, init/fini and whatever symbol is passed to dladdr would have to be private/hidden.

Maybe one final pragma to make the symbols COMDAT.

--
September 28, 2015
https://issues.dlang.org/show_bug.cgi?id=15060

Jacob Carlborg <doob@me.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |doob@me.com

--- Comment #7 from Jacob Carlborg <doob@me.com> ---
(In reply to Martin Nowak from comment #4)
> Can someone please try to fix this properly in druntime?
> If it's not doable using the dyld API, I might work on adding init/fini
> calls to any OSX binary (similar to what we do on ELF).

I've looked in the source code of dyld. There's no code that removes anything from the list of callbacks. I don't see any other way than using the init/fini calls.

--
September 28, 2015
https://issues.dlang.org/show_bug.cgi?id=15060

--- Comment #8 from bitwise <nicolas.jinchereau@gmail.com> ---
>> ponce 2015-09-18 09:47:37 UTC
>> Hacky workaround found by bitwise and Martin Nowak:
>> http://forum.dlang.org/post/lldikuutgrpmmyuhfukr@forum.dlang.org

I suppose I should note that I was expanding on Jacob's solution ;)

--
October 01, 2015
https://issues.dlang.org/show_bug.cgi?id=15060

--- Comment #9 from ponce <aliloko@gmail.com> ---
If this need back-end support, maybe Walter could implement global ctor/dtor like in LDC?

@bitwise: how much would you take to do it? :))


FWIW, I'm having problem with the workaround (calling dyld_register_image_state_change_handler crash). It's as if dyld_register_image_state_change_handler has a different signature or calling convention in 32-bit.

--
October 01, 2015
https://issues.dlang.org/show_bug.cgi?id=15060

--- Comment #10 from Jacob Carlborg <doob@me.com> ---
(In reply to ponce from comment #9)
> If this need back-end support, maybe Walter could implement global ctor/dtor like in LDC?

DMD already does what's necessary for ELF (Linux, FreeBSD). Just do the same
for Mach-O and OS X.

> FWIW, I'm having problem with the workaround (calling dyld_register_image_state_change_handler crash). It's as if dyld_register_image_state_change_handler has a different signature or calling convention in 32-bit.

The declaration of dyld_register_image_state_change_handler is available here [1]. The declaration of "dyld_image_info" [2] and "mach_header" [3].

Looking at your implementation, both the function pointer for the callback and the function it points to need to be declared as extern(C).

[1]
http://www.opensource.apple.com/source/dyld/dyld-96.2/include/mach-o/dyld_priv.h
[2]
http://opensource.apple.com/source/dyld/dyld-132.13/include/mach-o/dyld_images.h
[3]
http://www.opensource.apple.com/source/xnu/xnu-1456.1.26/EXTERNAL_HEADERS/mach-o/loader.h

--
« First   ‹ Prev
1 2