D-Programming-GDC/GDC — pull request #83 by jpf91 (2014-08-11 10:33:59+00:00)
Title: WIP: shared library support

@ibuclaw:
This implements shared library support for GDC. I initially hoped to find a cross-platform (runtime linker independent) solution, but plugin loading in D can't be done without special linker support, so I just followed the DMD implementation.

Notable changes: DMD emits a call to `_d_dso_registry` into every object file and uses COMDAT groups to make sure only one call is in the final executable. I'm not sure if we can do this with GCC: Although I can easily make the function COMDAT, I don't know if it's possible to mark the DECL_STATIC_CONSTRUCTOR as COMDAT. So I ended up with one function per shared library but many calls to this function as every object file places one link to this function into the constructors array.
So instead of generating this `_d_dso_registry` call in the compiler I wrote a small `__sharedlib.c` helper which does the call. It must be linked once into every shared library and the main application as well. It's being located by gcc like the `crt0.o` files with a 'startfile'-spec.
I actually wonder if we should rewrite `d-spec.cc` to use spec strings? But I'm not sure if we can do that without patching gcc?

Changes to linker scripts are not necessary: Theres a `ld` feature which automatically adds `__start_[section]/__stop_[section]` symbols for orphan sections. We'd only have to modify the scripts to support `--gc-sections`: https://sourceware.org/binutils/docs/ld/Orphan-Sections.html#Orphan-Sections

Things to fix:
* The phobos unittests fail with the sections_linux.d changes, even when linking statically. I've debugged this and it doesn't seem to be a bug with shared library code: previously we just didn't call the destructors when the application called `exit()`. But now we do, as `exit()` calls the C destructors which then call `_d_dso_registry` which calls the D destructors. DMD does the same thing and this seems to be correct, so this is actually an unrelated bug which was hidden previously.
* `runnable/mangle.d` fails: mangle.d emits an extern reference to `_D6object12__ModuleInfoZ`. It's undefined in the object file, but when linking `_D6object12__ModuleInfoZ` actually gets defined in the application BSS instead of staying undefined and being resolved by the runtime linker to the symbol in druntime. Do you know what could cause this?
* `runnable/untag` doesn't compile: `unresolvable R_X86_64_TPOFF32 relocation against symbol '_D3std6getopt10optionCharw'`. It compiles when using `-fPIC` but I though compiling the application with `-fPIC` shouldn't be necessary? Any idea about this?
* Non-linux platforms (should be simple)