diff options
author | Matthias von Faber <mvf@gmx.eu> | 2017-08-28 16:49:55 +0300 |
---|---|---|
committer | Matthias von Faber <mvf@gmx.eu> | 2017-09-03 20:14:40 +0300 |
commit | 2903f3bed27bb32684b060a03fa75365e28c7e12 (patch) | |
tree | e7b2478a47991879eb4122ac6530b51e96e33ef0 /overlay_gl | |
parent | f2cbebdce87ac68929effb18e2ced7bbc58f89f9 (diff) |
overlay_gl: linux: only assume absolute dynamic entries on glibc.
This fixes a crash in libmumble's library constructor when built against
the musl libc.
The code that locates libc's dlsym(3) relied on addresses in dynamic
entries in the link map returned by dlopen(3) to always be absolute.
This seems to be specific to glibc though, so add a glibc feature test.
Diffstat (limited to 'overlay_gl')
-rw-r--r-- | overlay_gl/init_unix.c | 11 |
1 files changed, 8 insertions, 3 deletions
diff --git a/overlay_gl/init_unix.c b/overlay_gl/init_unix.c index 1b5cfd685..03d0ddb63 100644 --- a/overlay_gl/init_unix.c +++ b/overlay_gl/init_unix.c @@ -152,19 +152,24 @@ static int find_odlsym() { int nchains = 0; ElfW(Sym) *symtab = NULL; const char *strtab = NULL; +#if defined(__GLIBC__) + const ElfW(Addr) base = 0; +#else + const ElfW(Addr) base = lm->l_addr; +#endif ElfW(Dyn) *dyn = lm->l_ld; while (dyn->d_tag) { switch (dyn->d_tag) { case DT_HASH: - nchains = *(int *)(dyn->d_un.d_ptr + 4); + nchains = *(int *)(base + dyn->d_un.d_ptr + 4); break; case DT_STRTAB: - strtab = (const char *) dyn->d_un.d_ptr; + strtab = (const char *)(base + dyn->d_un.d_ptr); break; case DT_SYMTAB: - symtab = (ElfW(Sym) *) dyn->d_un.d_ptr; + symtab = (ElfW(Sym) *)(base + dyn->d_un.d_ptr); break; } dyn ++; |