On Fri, 2009-05-01 at 09:33 +0100, Duncan Coutts wrote: > Currently I'm getting some test failures for WAY=dyn. I'm not posting > the full list at the moment as I'm not convinced it's quite accurate. > I'll post an update later.
Unexpected failures: 1679(dyn) 2469(dyn) 2594(dyn) T1969(dyn,normal) annrun01(dyn,normal) conc021(dyn) conc039(dyn) conc040(dyn) concprog001(dyn,normal) fed001(dyn) ffi002(dyn) ffi006(dyn) ffi007(dyn) ffi008(dyn) ffi009(dyn) ffi011(dyn) ffi013(dyn) ffi016(dyn) ffi019(dyn) ghci024(normal) hs-boot(dyn) length001(dyn) recomp005(normal) recomp006(normal) space_leak_001(dyn,normal) tcrun007(dyn,normal) I'm working under the assumption that ones that fail in the "normal" way are not the fault of dyn libs. So the specific dyn way failures are: 1679(dyn) 2469(dyn) 2594(dyn) conc021(dyn) conc039(dyn) conc040(dyn) fed001(dyn) ffi002(dyn) ffi006(dyn) ffi007(dyn) ffi008(dyn) ffi009(dyn) ffi011(dyn) ffi013(dyn) ffi016(dyn) ffi019(dyn) hs-boot(dyn) length001(dyn) >From running the ffi tests it looks like they all have the same cause. The first problem I described in the previous email. I'll try and fix that and then look at the other test failures. > I've investigated ffi002. This test ffi exports a Haskell foo function > and calls it from a C main function. Two things go wrong when building > this with -dynamic. > > 1. We do not compile the _stub.c with -fPIC. I talked this morning with Simon Marlow and we think we understand this behaviour and why using -fPIC solves it > Let's first be clear what is happening: > > compile ffi002.hs -> ffi002.o with -dynamic > compile ffi002_c.c -> ffi002_c.o without any special options > compile ffi002_stub.c -> ffi002_stub.o without any special options > link ffi002.o ffi002_c.o ffi002_stub.o with libHSrts.so, etc to make a > binary. The symbol "main" lives in ffi002_c.c. > > When compiling the .hs to a .o we have to use -dynamic otherwise the > final binary does not link. In ghc, -dynamic and -fPIC have related but different meanings when compiling Haskell code. -dynamic also has a meaning at link time. gcc has no corresponding -dynamic flag. It does have -fPIC. In ghc when compiling .hs to .o, -dynamic means that references to functions (and static data like info tables) from other packages goes via dynamic references (a GOT on most architectures). For Haskell code we must use this to be able to link to code in shared Haskell libs. For C (in unix), one does not need to do anything special to get code that can link to functions from shared libs. The C compiler and linker can make everything work automagically. (In comparison, on Windows, calls to functions from dlls have to be marked explicitly). This even works for references to static data from shared libs. However it does not work for reference static data in a Haskell shared lib, because we're not quite following standard conventions. The way it would work is that the static linker would reserve space in the final binary for the static data and arrange to copy it during dynamic linking from the shared lib into the static location in the executable binary (this allows the final static exe to have a fixed address for the data reference). That works for global static data in C code because the C compiler tells the assembler and linker how big each piece of static data is (via a .size directive). However for Haskell code we do not because under the current scheme we cannot. Info tables would have negative size because we identify them by a pointer to the end not to the beginning. So that explains why we get linker warnings like: dynamic variable `base_GHCziTopHandler_runIO_closure' is zero size However, if we compile the C code that is trying to reference this dynamic variable using -fPIC then it uses a different way of addressing the static data (going via the GOT I think). So then there's no need for the static linker to try and fix things up by copying (which it cannot do in our case). So, that explains why it is that we did not need to compile ffi002_c.c using -fPIC but we do need to compile ffi002_stub.c with -fPIC. The latter uses references to static data from a Haskell shared lib while the former only references functions from a Haskell shared lib. So, the solution is indeed to compile the _stub.c files using gcc -fPIC, when the .hs file is being compiled with ghc -dynamic. Note that this problem could happen with any hand written C code that references static data in a Haskell shared lib, however most C code will not be doing that. Still, it's probably worth putting somewhere in the docs that if one gets linker warnings about symbols being zero size to compile the C code with -fPIC. Sadly it's only a warning from the linker, the link succeeds but the programs segfault. > 2. The main symbol lives in the libHSrts.so which fails if we're using a > C main function We're going to try moving Main.c out of the rts and keep it as a separate Main.o which we'll link into every program, unless one uses the -no-hs-main flag. Duncan _______________________________________________ Cvs-ghc mailing list [email protected] http://www.haskell.org/mailman/listinfo/cvs-ghc
