GNU dlopen(3) differs from POSIX/IEEE

Suprateeka R Hegde hegdesmailbox@gmail.com
Fri Jan 1 00:00:00 GMT 2016


(I was away from work. Apologize for the delay in response)

On 13-Jun-2016 11:21 PM, Carlos O'Donell wrote:
> On 06/13/2016 10:48 AM, Suprateeka R Hegde wrote:
>> 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.
>
> Correct, you don't get a PLT entry for foo unless it's in a shared
> library at link-edit time.
>
> Could you actually provide the exact steps you used in a GNU/Linux-
> --based system to produce the final executable?
>
> My experience is that you will either see a failure at link-edit
> time, failure at runtime (missing libfoo.so, undefined symbol foo),
> and will never get to the point where you can run the application
> and get a segfault. I'm curious to see exactly the way you constructed
> the scenario.

This is just to show there are ways to bring symbols to global space at 
runtime. LD_PRELOAD is one way. dlopen(3) with RTLD_GLOBAL would be 
another way, but on GNU based system it is not as per POSIX/IEEE specs.

So I tested for at least the LD_PRELOAD way. Here are the exact steps:

---
$ 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"); }

$ cat libjunk.c
#include <stdio.h>
void junk(void) { printf("Junky\n"); }


$ cc -fpic -shared libfoo.c -o libfoo.so
$ cc main.c -ldl -L. -lfoo # Gets a JUMP_SLOT for foo
$ cp libfoo.so libfoo1.so

$ # Now change libfoo.so not to contain foo. In other words
$ # not to resolve foo from startup libfoo.so. Keep it unresolved
$ # for lazy bind to happen to a runtime-brought-in global foo.

$ cc -fpic -shared libjunk.c -o libfoo.so
$ LD_PRELOAD=./libfoo1.so ./a.out
In foo
---

As you see, program works fine and foo is lazy bound to foo from 
libfoo1.so, which has been brought in at runtime without being there at 
link-edit time. The same case would have worked even without LD_PRELOAD, 
and with only dlopen-RTLD_GLOBAL if the GNU dlopen(3) matched the spec 
defined by POSIX/IEEE.

> Therefore if the application's global symbol references all must be
> defined before it starts there is no possibility for dlopen with
> RTLD_GLOBAL to add symbols to the global scope that can be used
> to result such symbols, because they are already resolved.

No possibility with current GNU implementation. But possible with 
POSIX/IEEE compliant dlopen(3). The test case works fine on other POSIX 
compliant system.

All I am saying is, dlopen(3) with RTLD_GLOBAL also should bring in foo 
at runtime to be compliant with POSIX.

--
Supra



More information about the Gnu-gabi mailing list