Interface loading and dynamic linking

Ben Gamari bgamari.foss at gmail.com
Sun Dec 22 17:34:25 UTC 2013


In trying to test my LLVM-dynamic linking changes, I've encountered some
builds which fail with,

    Bad interface file: dist-install/build/GHC/CString.hi
        mismatched interface file ways (wanted "dyn", got "")

during `make install`. The failing command is `ghc-stage2`, invoked by
`ghc-cabal`,

    ../../inplace/bin/ghc-stage2 '-B/opt/exp/ghc/root-ghc-7.8-dyn/lib/ghc-7.7.20131221' '--abi-hash' '-fbuilding-cabal-package' '-O' '-outputdir' 'dist-install/build' '-odir' 'dist-install/build' '-hidir' 'dist-install/build' '-stubdir' 'dist-install/build' '-i' '-idist-install/build' '-i.' '-idist-install/build/autogen' '-Idist-install/build/autogen' '-Idist-install/build' '-optP-include' '-optPdist-install/build/autogen/cabal_macros.h' '-package-name' 'ghc-prim-0.3.1.0' '-hide-all-packages' '-no-user-package-db' '-package-id' 'builtin_rts' '-XHaskell2010' 'GHC.CString' 'GHC.Classes' 'GHC.Debug' 'GHC.IntWord64' 'GHC.Magic' 'GHC.PrimopWrappers' 'GHC.Tuple' 'GHC.Types' 'GHC.Prim' '-package-name' 'ghc-prim'

The build is on an x86_64 box with `build.mk` containing,

    GhcDebugged = YES
    DYNAMIC_BY_DEFAULT = YES

    # Roughly BuildFlavour=quick-llvm without disabling dynamic linking
    SRC_HC_OPTS        = -H64m -O0 -fllvm # -keep-llvm-files
    GhcStage1HcOpts    = -O -fllvm
    GhcStage2HcOpts    = -O0 -fllvm
    GhcLibHcOpts       = -O -fllvm
    SplitObjs          = NO
    HADDOCK_DOCS       = NO
    BUILD_DOCBOOK_HTML = NO
    BUILD_DOCBOOK_PS   = NO
    BUILD_DOCBOOK_PDF  = NO

    
I've spent the morning tracing through the interface loading code and
have finally met an impasse. As far as I can tell, the relevant
subset of the call graph is,

    LoadIface.lhs: loadInterface
      LoadIface.lhs : findAndReadIface
        Finder.hs: findExactModule
          Finder.hs: findHomeModule
            Finder.hs: homeSearchCache
              Finder.hs: findHomeModule
    
        findAndReadIface(read_file)
        findAndReadIface(checkBuildDynamicToo)
          whenGeneratingDynamicToo
            TcRnMonad.hs: withDoDynamicToo
              DynFlags.hs: dynamicTooMkDynamicDynFlags
                findAndReadIface(read_file)
    
        where
          findAndReadIFace(read_file)
            LoadIface.lhs : readIface
              BinIface.hs : readBinIface

Up until `checkBuildDynamicToo` the dynflags have,

    ways dflags     == [WayDyn]
    buildTag dflags == "dyn"
    hiSuf dflags    == "hi"
    dynHiSuf dflags == "dyn_hi"

Given this, it's perhaps unsurprising that `readBinIface` gets quite
confused when it attempts to read `dist-install/build/GHC/CString.hi` to
find that it was compiled with a null tag, not `dyn` as expected.
If I add `-static` to the command line the build succeeds. However,
adding `-dynamic` or `-dynamic-too` or omitting all of the above (due to
`DYNAMIC_BY_DEFAULT`) all fail.

It seems that `findAndReadIface` attempts to account for
`-dynamic-too` but I don't see how the approach should work:
it tries to first load the static interface file (but with
`ways==[WayDyn]`) then tries again to load the interface using
`DynFlags` and .hi file name constructed for the dynamic case. I can't
see how this would ever work as `readBinIface` will expect to see a
dynamic interface file due to the DynFlags' ways.

It's also unclear how the `-dynamic` case (not `-dynamic-too`) is handled under this
scheme. I would have thought that running with `-dynamic` would cause
`hiSuf == dynHiSuf` but I can't find any code to suggest this is the case.

Could someone offer some insight into how interface loading, `-dynamic`,
and `-dynamic-too` are supposed to interact?

Thanks,

- Ben
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 489 bytes
Desc: not available
URL: <http://www.haskell.org/pipermail/ghc-devs/attachments/20131222/ea8cd20c/attachment.sig>


More information about the ghc-devs mailing list