[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
GNU dlopen(3) differs from POSIX/IEEE
Hi
The RTLD_GLOBAL flag of dlopen(3) under POSIX/IEEE standards says "The
executable object file's symbols shall be made available for relocation
processing of any other executable object file".
(http://pubs.opengroup.org/onlinepubs/9699919799/functions/dlopen.html)
However, on a GNU/Linux system, the manpage says "The symbols defined by
this library will be made available for symbol resolution of
subsequently loaded libraries".
And yes, there is a difference between the two. According to the
POSIX/IEEE one, the symbols from a dlopened library is available for
symbol resolution in the executable (a.out) also. The GNU one seems to
restrict it "subsequently" opened objects only, and not "any" object.
The following case fails on GNU/Linux, but works on other POSIX
compliant systems.
---
$ cat main.c
#include <dlfcn.h>
extern void foo(void);
int main()
{
dlopen("./libfoo1.so", RTLD_GLOBAL);
foo();
return 0;
}
$ cat libfoo.c
#include <stdio.h>
void foo(void) { printf("In foo\n"); }
$ cc -fpic -shared libfoo.c -o libfoo.so
$ cc main.c -ldl # Read Note-1 at the end
$ ./a.out
Segmentation fault (core dumped)
$ LD_PRELOAD=./libfoo1.so ./a.out
In foo
---
That means dlopen RTLD_GLOBAL was not effective. LD_PRELOAD was
effective. Of course the entire exercise is for lazy bind mode.
Is there any reason why GNU differes here? Does it mean the GNU variant
is not POSIX/IEEE compliant?
--
Supra
Note-1:
Without provding libfoo on the link line, I could not get a JUMP_SLOT
for foo. So I provided -lfoo for the link-edit phase and then renamed
libfoo.so to libfoo1.so and also created a dummy libfoo.so without foo.
This way, I could get a JUMP_SLOT for foo. This hack was not necessary
on other platforms as foo gets a PLT entry even without definition. By
getting a JUMP_SLOT, I could verify if LD_PRELOAD works in this case.