On 19-Sep-07, at 9:23 PM, Sven Panne wrote:

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 strange behaviour we are seeing is definitely triggered by RTLD_NOW, at least on 32-bit linux. Do we really need RTLD_NOW, or can we work around the problem by just leaving that out?

==== lib.c
int data = 42;

==== main.c
#define _GNU_SOURCE
#include <dlfcn.h>
#include <stdio.h>
extern int data;

int main()
{
    void *handle1, *handle2, *handle3;
    handle1 = dlopen( "./liblib.so", RTLD_GLOBAL );
    handle2 = dlopen( "./liblib.so", RTLD_NOW | RTLD_GLOBAL );
    handle3 = dlopen( "./liblib.so", RTLD_GLOBAL );
    printf("&data == %p\n", &data );
printf("dlsym(handle1, \"data\") == %p\n", dlsym( handle1, "data" ) ); printf("dlsym(handle2, \"data\") == %p\n", dlsym( handle2, "data" ) ); printf("dlsym(handle3, \"data\") == %p\n", dlsym( handle3, "data" ) );
    printf("dlsym(RTLD_DEFAULT, \"data\") == %p\n",
           dlsym( RTLD_DEFAULT, "data" ) );

    return 0;
}

===
[EMAIL PROTECTED]:~/Experiments/DynamicLinkingWeirdness$ cc -shared - o liblib.so lib.c [EMAIL PROTECTED]:~/Experiments/DynamicLinkingWeirdness$ cc main.c - ldl -L. -llib [EMAIL PROTECTED]:~/Experiments/DynamicLinkingWeirdness$ LD_LIBRARY_PATH=. ./a.out
&data == 0x80498c0
dlsym(handle1, "data") == 0x80498c0
dlsym(handle2, "data") == 0xb7eff518
dlsym(handle3, "data") == 0x80498c0
dlsym(RTLD_DEFAULT, "data") == 0x80498c0
===

So, handles to loaded using RTLD_NOW are a problem, but non-RTLD_NOW handles are fine, even if there are RTLD_NOW handles around, too.

Not using RTLD_NOW might delay reporting of some errors, but I can't think of any other problems right now. If this works, then we are only in trouble on x86_64 once the data reference happens to be outside the 32 bit range (this is why, in general, we'll need -fPIC anyway).


Cheers,

Wolfgang



_______________________________________________
Cvs-ghc mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/cvs-ghc

Reply via email to