diff options
author | Mikkel Krautz <mikkel@krautz.dk> | 2015-11-23 03:22:34 +0300 |
---|---|---|
committer | Mikkel Krautz <mikkel@krautz.dk> | 2015-11-23 03:24:42 +0300 |
commit | 3a356a2a13f39578b9b308bbb9e8970bf9d17978 (patch) | |
tree | b1d5dc050bb0352a8d162dce4dee8ba70cd067da /overlay_gl | |
parent | 0e4070c11d884bd986ea47fd486da813c7090326 (diff) |
overlay_gl: port to FreeBSD.
Refactor the code to find the RTLD's dlsym() symbol into a function,
find_odlsym(). Implement a FreeBSD-specific version of the code.
Verified against 'glxgears'.
Diffstat (limited to 'overlay_gl')
-rw-r--r-- | overlay_gl/init_unix.c | 106 | ||||
-rw-r--r-- | overlay_gl/overlay_gl.pro | 4 |
2 files changed, 91 insertions, 19 deletions
diff --git a/overlay_gl/init_unix.c b/overlay_gl/init_unix.c index 22ff9b126..985f7b83e 100644 --- a/overlay_gl/init_unix.c +++ b/overlay_gl/init_unix.c @@ -167,25 +167,13 @@ void *dlsym(void *handle, const char *name) { return symbol; } -__attribute__((constructor)) -static void initializeLibrary() { - if (odlsym) - return; - - if (getenv("MUMBLE_OVERLAY_DEBUG")) { - bDebug = true; - } else { - bDebug = false; - } - - bCursorAvail = false; - - ods("Mumble overlay library loaded"); +static int find_odlsym() { +#if defined(__linux__) void *dl = dlopen("libdl.so.2", RTLD_LAZY); if (!dl) { ods("Failed to open libdl.so.2"); } else { - int i; + int i = 0; struct link_map *lm = (struct link_map *) dl; int nchains = 0; ElfW(Sym) *symtab = NULL; @@ -208,13 +196,95 @@ static void initializeLibrary() { dyn ++; } ods("Iterating dlsym table %p %p %d", symtab, strtab, nchains); - for (i=0;i<nchains;++i) { + for (i = 0; i < nchains; i++) { // ELF32_ST_TYPE and ELF64_ST_TYPE are the same - if (ELF32_ST_TYPE(symtab[i].st_info) != STT_FUNC) + if (ELF32_ST_TYPE(symtab[i].st_info) != STT_FUNC) { continue; - if (strcmp(strtab+symtab[i].st_name, "dlsym") == 0) + } + if (strcmp(strtab+symtab[i].st_name, "dlsym") == 0) { odlsym = (void*)lm->l_addr + symtab[i].st_value; + } + } + if (odlsym == NULL) { + goto err; } ods("Original dlsym at %p", odlsym); } + + return 0; +#elif defined(__FreeBSD__) + int i = 0; + struct link_map *lm = NULL; + int nchains = 0; + Elf_Sym * symtab = NULL; + const char *strtab = NULL; + + if (dlinfo(RTLD_SELF, RTLD_DI_LINKMAP, &lm) == -1) { + ods("Unable to acquire link_map: %s", dlerror()); + goto err; + } + + while (lm != NULL) { + if (!strcmp(lm->l_name, "/libexec/ld-elf.so.1")) { + break; + } + lm = lm->l_next; + } + if (lm == NULL) { + goto err; + } + + Elf_Dyn *dyn = (Elf_Dyn *) lm->l_ld; + + while (dyn->d_tag) { + switch (dyn->d_tag) { + case DT_HASH: + nchains = *(int *)((uintptr_t)lm->l_addr + (uintptr_t)dyn->d_un.d_ptr + 4); + break; + case DT_STRTAB: + strtab = (const char *)((uintptr_t)lm->l_addr + (uintptr_t)dyn->d_un.d_ptr); + break; + case DT_SYMTAB: + symtab = (Elf64_Sym *)((uintptr_t)lm->l_addr + (uintptr_t)dyn->d_un.d_ptr); + break; + } + dyn++; + } + ods("Iterating dsym table %p %p %d", symtab, strtab, nchains); + for (i = 0; i < nchains; i++) { + if (ELF_ST_TYPE(symtab[i].st_info) != STT_FUNC) { + continue; + } + if (strcmp(strtab + symtab[i].st_name, "dlsym") == 0) { + odlsym = (void *) lm->l_addr + symtab[i].st_value; + } + } + if (odlsym == NULL) { + goto err; + } + ods("Original dlsym at %p", odlsym); + + return 0; +#endif +err: + return -1; +} + +__attribute__((constructor)) +static void initializeLibrary() { + if (odlsym) + return; + + if (getenv("MUMBLE_OVERLAY_DEBUG")) { + bDebug = true; + } else { + bDebug = false; + } + + bCursorAvail = false; + + ods("Mumble overlay library loaded"); + if (find_odlsym() == -1) { + ods("Failed to find original address of dlsym()."); + } } diff --git a/overlay_gl/overlay_gl.pro b/overlay_gl/overlay_gl.pro index 9651d8e62..3dbabf522 100644 --- a/overlay_gl/overlay_gl.pro +++ b/overlay_gl/overlay_gl.pro @@ -16,7 +16,9 @@ unix:!macx { TARGET = mumble$(TARGET_ADD) DEFINES += TARGET_UNIX - LIBS *= -lrt -ldl + linux { + LIBS *= -lrt -ldl + } QMAKE_CFLAGS *= -fvisibility=hidden $(CFLAGS_ADD) QMAKE_LFLAGS -= -Wl,--no-undefined |