dynamic linking test failures
duncan.coutts at worc.ox.ac.uk
Fri May 1 07:05:14 EDT 2009
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.
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:
>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
More information about the Cvs-ghc