[ People who want to take a shortcut can immediately jump to the end and read
what has to be done to fix things. ;-) ]
On Wednesday 19 September 2007 00:41, Wolfgang Thaller wrote:
> I guess I could find some time to play around with it on the weekend.
> I don't have an x86_64-linux box available right now, but I might
> either try some virtualisation software or just do a rough sketch and
> leave you to do the debugging ;-). [...]
Deal! :-) I've played around a little bit more with dynamic linking, and made
the example even more similar to what we do in Linker.c:
---------- strange.c -------------------------------------------------------
#define _GNU_SOURCE
#include <dlfcn.h>
#include <stdio.h>
// cut-n-paste from freeglut, used in
// #define GLUT_BITMAP_8_BY_13 ((void *) &glutBitmap8By13)
extern void* glutBitmap8By13;
int main(void) {
void *defaultHandle = RTLD_DEFAULT;
int* p1 = (int*)dlsym(defaultHandle, "glutBitmap8By13");
void* glutHandle = dlopen("libglut.so", RTLD_NOW | RTLD_GLOBAL);
int* p2 = (int*)dlsym(glutHandle, "glutBitmap8By13");
int *p3 = (int*)dlsym(defaultHandle, "glutBitmap8By13");
// printf("%p\n", &glutBitmap8By13);
printf("%p %p %p\n", p1, p2, p3);
return 0;
}
----------------------------------------------------------------------------
[EMAIL PROTECTED]:~> gcc strange.c -ldl && ./a.out
(nil) 0x2b2c8611cf00 0x2b2c8611cf00
----------------------------------------------------------------------------
OK, that looks fine. Now let's add -lglut to the compilation:
----------------------------------------------------------------------------
[EMAIL PROTECTED]:~> gcc strange.c -ldl -lglut && ./a.out
0x2b2d6e3d6f00 0x2b2d6e3d6f00 0x2b2d6e3d6f00
----------------------------------------------------------------------------
Again, not too surprising. Finally we uncomment the printf:
----------------------------------------------------------------------------
[EMAIL PROTECTED]:~> gcc strange.c -ldl -lglut && ./a.out
0x601040
0x601040 0x2b1cbbdfbf00 0x601040
----------------------------------------------------------------------------
Desaster! This is not what we want, but this can be fixed by -fpic:
----------------------------------------------------------------------------
[EMAIL PROTECTED]:~> gcc strange.c -ldl -lglut -fpic && ./a.out
0x2b67ad9c0f00
0x2b67ad9c0f00 0x2b67ad9c0f00 0x2b67ad9c0f00
----------------------------------------------------------------------------
I think this clearly shows (at least on Linux x86_64) that code which
references data in dynamically loaded libraries *must* itself be position
independent, because then, and only then, the equation
dlsym(RTLD_DEFAULT, "foo") == &foo
is guaranteed to hold. Currently we ignore this fact, and we are lucky that on
all similar platforms no data is accessed this way. Access to errno currently
only works because on all platforms with threading, errno is a macro for a
function call, and references to code do work (via an indirection). GLUT is
not so lucky, so some parts of the GLUT binding currently fail from within
GHCi. (*)
The unavoidable consequence is that Cabal must add -fpic on these platforms
when compiling C code that might later be loaded by GHCi, and GHCi itself
must be able to handle all necessary relocations. Furthermore, GHC's code
generator has to take this into account when generating code for:
foreign import "&blah" :: Ptr Foo -- (**)
If these fixes won't make their way into GHC 6.8.1, we should at least put a
big fat warning into the documentation somewhere that our handling of dynamic
libs is broken on some platforms.
Cheers,
S.
(*) It is very debatable if accessing data in dynamic libs directly is nice,
but this is how GLUT works and will continue to do so because of binary
compatibility. The data itself is actually never accessed in freeglut, only
pointer comparisons are done, but the net effect is the same.
(**) System.Console.Readline.hsc has code like this to import rl_line_buffer.
GHCi itself uses this, and it only works because we explictly link GHCi
against the dynamic readline library. If GHCi loaded the readline package
dynamically, things would fail in a similar way to the GLUT problem.
_______________________________________________
Cvs-ghc mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/cvs-ghc