Skip to content

Runtime linker performs eager loading of all object files

The runtime linker seems to be re-exporting some of the symbols of libmingwex from the rts archive (using SymI_HasProto). Only a very small subset of symbols are re-exporting.

If a symbol is needed that isn't re-exported (e.g. log1p) then this code can't be run in GHCi because it will result in a duplicate symbols error.

A workaround

The rts seems to be a special case again. The linker seems to ignore the extra-libraries from the package.conf, which explains why you can put anything you want in there and it'll still compile.

128 emptyPLS :: DynFlags -> PersistentLinkerState 
129 emptyPLS _ = PersistentLinkerState { 
130                         closure_env = emptyNameEnv, 
131                         itbl_env    = emptyNameEnv, 
132                         pkgs_loaded = init_pkgs, 
133                         bcos_loaded = [], 
134                         objs_loaded = [], 
135                         temp_sos = [] } 
136 
 
137   -- Packages that don't need loading, because the compiler 
138   -- shares them with the interpreted program. 
139   -- 
140   -- The linker's symbol table is populated with RTS symbols using an 
141   -- explicit list.  See rts/Linker.c for details. 
142   where init_pkgs = [rtsUnitId] 

I've tried 2 approaches which haven't worked completely:

  1. I tried removing the symbols from the export list and adding libmingwex to the rts's package.confand have it just link against it. But turns out the rts's package.conf is ignored on all platforms. I didn't want to have to make an exception for Windows here and I don't know why the other platforms also ignore it so I abandoned this approach.
  2. I tried marking the symbols we're re-exporting as weak symbols, so there wouldn't be a change to existing code and would allow you to link against libmingwex. But unfortunately because of when the other libraries specified by -l are linked in, some of the symbols have already been used and thus aren't weak anymore. So I still get duplicate link errors.

What I want to try now is leaving them as weak symbols, but loading libmingwex.a at rts initialization time. Much like how kernel32 is loaded. This is hopefully early enough that the symbols haven't been used yet.

Example

-- LogFloat.hs
module Main (main) where

import Data.Number.LogFloat (log1p)

main :: IO ()
main = print $ log1p 1.0

runGhc LogFloat.hs will fail:

Loading package logfloat-0.13.3.3 ... 
linking ... 
LogFloat.hs: ...\x86_64-windows-ghc-7.11.20151123\logfloat-0.13.3.3-4JZYNCXKwghOD60rvMUAcn\HSlogfloat-0.13.3.3-4JZYNCXKwghOD60rvMUAcn.o: unknown symbol `log1p' 

LogFloat.hs: LogFloat.hs: unable to load package `logfloat-0.13.3.3' 
Edited by Tamar Christina
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information