[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