[GHC] #10352: Properly link Haskell shared libs on all systems
GHC
ghc-devs at haskell.org
Fri Aug 12 19:51:40 UTC 2016
#10352: Properly link Haskell shared libs on all systems
-------------------------------------+-------------------------------------
Reporter: duncan | Owner: Phyx-
Type: task | Status: new
Priority: normal | Milestone:
Component: Compiler | Version: 7.11
(Linking) |
Resolution: | Keywords:
Operating System: Unknown/Multiple | Architecture:
| Unknown/Multiple
Type of failure: None/Unknown | Test Case:
Blocked By: | Blocking: 5987
Related Tickets: | Differential Rev(s):
Wiki Page: |
-------------------------------------+-------------------------------------
Comment (by Phyx-):
I'm having a hard time getting this to work on Windows which is what is
causing the delay.
The issue is that normally you'd be able to do this easily by delay
loading the dll. This is done by creating a delay loading import library
which essentially, instead of putting the symbols in the IAT of the PE
file instead links statically against stubs.
These stubs allow it to then load the DLL only on first call of a related
function. This is done by those adding a level of indirection.
(mingw-w64's implementation is here if curious
https://github.com/mirror/mingw-w64/blob/master/mingw-w64-crt/misc/delayimp.c)
The issue is that this approach has a major limitation: It only works for
Functions!
This limitation is described here https://msdn.microsoft.com/en-
us/library/yx1x886y.aspx
But essentially this is because exported `const data` entries end up
becoming stubs too. (empty stubs, but stubs in any case). This address is
resolved at link time (because you're linking against the stub instead of
the IAT entry being added to the Windows Loader can later resolve it).
One way to work around this is to replace constant imports such as
{{{
__declspec(dllimport) extern FooS_t fooStruct;
}}}
With explicit loads using MACROs:
{{{
FooS_t fst = *(FooS_t*)GetProcAddress(GetModuleHandle("foo"),
"fooStruct");
}}}
This works, but I would have to track down each and every use of constants
in the RTS and change them to this or to make them functions (e.g
`getFooStruct()`).
What I am investigating now is a third approach, using an intermediate
proxy dll. Link normally against the proxy to the loader resolves the
addresses of const data as it should, but have the proxy "forward" the
requests to the right dll.
This can be done because when the linker looks up symbols in the IAT the
OS allows for hooks in the target library to override the returned
address. This should allow me to use the proxy to choose at runtime which
runtime to use.
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/10352#comment:14>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the ghc-tickets
mailing list