|
10 | 10 | #include <link.h> |
11 | 11 | #include <unistd.h> |
12 | 12 | #include <errno.h> |
| 13 | +#include <fnmatch.h> |
13 | 14 | #ifndef _DLFCN_H |
14 | 15 | #include <dlfcn.h> |
15 | 16 | #endif |
|
38 | 39 | #include "symbols.h" |
39 | 40 | #include "cleanup.h" |
40 | 41 | #include "globalsymbols.h" |
| 42 | +#include "elfhacks.h" |
41 | 43 | #ifdef DYNAREC |
42 | 44 | #include "dynablock.h" |
43 | 45 | #endif |
@@ -1940,72 +1942,60 @@ int NeededLibs(elfheader_t* h) |
1940 | 1942 |
|
1941 | 1943 | typedef struct search_symbol_s{ |
1942 | 1944 | const char* name; |
1943 | | - void* addr; |
1944 | | - void* lib; |
| 1945 | + void* addr; |
1945 | 1946 | } search_symbol_t; |
1946 | | -int dl_iterate_phdr_findsymbol(struct dl_phdr_info* info, size_t size, void* data) |
| 1947 | + |
| 1948 | +int dl_iterate_phdr_findsymbol(eh_obj_t* obj, search_symbol_t* s) |
1947 | 1949 | { |
1948 | | - search_symbol_t* s = (search_symbol_t*)data; |
| 1950 | + // special case for dlsym -- it's not a versionned symbol in libMangoHud_shim.so. |
| 1951 | + if (!fnmatch("*libMangoHud_shim.so*", obj->name, 0) && !strcmp(s->name, "dlsym")) { |
| 1952 | + eh_find_sym(obj, "dlsym", &s->addr); |
| 1953 | + eh_destroy_obj(obj); |
| 1954 | + return !!s->addr; |
| 1955 | + } |
1949 | 1956 |
|
1950 | | - for(int j = 0; j<info->dlpi_phnum; ++j) { |
1951 | | - if (info->dlpi_phdr[j].p_type == PT_DYNAMIC) { |
1952 | | - ElfW(Sym)* sym = NULL; |
1953 | | - ElfW(Word) sym_cnt = 0; |
| 1957 | + for (int j = 0; j < obj->phnum; ++j) { |
| 1958 | + if (obj->phdr[j].p_type == PT_DYNAMIC) { |
1954 | 1959 | ElfW(Verdef)* verdef = NULL; |
1955 | 1960 | ElfW(Word) verdef_cnt = 0; |
1956 | | - char *strtab = NULL; |
1957 | | - ElfW(Dyn)* dyn = (ElfW(Dyn)*)(info->dlpi_addr + info->dlpi_phdr[j].p_vaddr); //Dynamic Section |
| 1961 | + char* strtab = NULL; |
| 1962 | + ElfW(Dyn)* dyn = (ElfW(Dyn)*)(obj->addr + obj->phdr[j].p_vaddr); |
1958 | 1963 | // grab the needed info |
1959 | | - while(dyn->d_tag != DT_NULL) { |
1960 | | - switch(dyn->d_tag) { |
| 1964 | + while (dyn->d_tag != DT_NULL) { |
| 1965 | + switch (dyn->d_tag) { |
1961 | 1966 | case DT_STRTAB: |
1962 | | - strtab = (char *)(dyn->d_un.d_ptr); |
| 1967 | + strtab = (char*)(dyn->d_un.d_ptr); |
1963 | 1968 | break; |
1964 | 1969 | case DT_VERDEF: |
1965 | | - verdef = (ElfW(Verdef)*)(info->dlpi_addr + dyn->d_un.d_ptr); |
| 1970 | + verdef = (ElfW(Verdef)*)(obj->addr + dyn->d_un.d_ptr); |
1966 | 1971 | break; |
1967 | 1972 | case DT_VERDEFNUM: |
1968 | 1973 | verdef_cnt = dyn->d_un.d_val; |
1969 | 1974 | break; |
1970 | 1975 | } |
1971 | 1976 | ++dyn; |
1972 | 1977 | } |
1973 | | - if(strtab && verdef && verdef_cnt) { |
1974 | | - if((uintptr_t)strtab < (uintptr_t)info->dlpi_addr) // this test is need for linux-vdso on PI and some other OS (looks like a bug to me) |
1975 | | - strtab=(char*)((uintptr_t)strtab + info->dlpi_addr); |
1976 | | - // Look fr all defined versions now |
1977 | | - ElfW(Verdef)* v = verdef; |
1978 | | - while(v) { |
1979 | | - ElfW(Verdaux)* vda = (ElfW(Verdaux)*)(((uintptr_t)v) + v->vd_aux); |
1980 | | - if(v->vd_version>0 && !v->vd_flags) |
1981 | | - for(int i=0; i<v->vd_cnt; ++i) { |
1982 | | - const char* vername = (strtab+vda->vda_name); |
1983 | | - if(vername && vername[0] && (s->addr = dlvsym(s->lib, s->name, vername))) { |
1984 | | - printf_log(/*LOG_DEBUG*/LOG_INFO, "Found symbol with version %s, value = %p\n", vername, s->addr); |
1985 | | - return 1; // stop searching |
1986 | | - } |
1987 | | - vda = (ElfW(Verdaux)*)(((uintptr_t)vda) + vda->vda_next); |
1988 | | - } |
1989 | | - v = v->vd_next?(ElfW(Verdef)*)((uintptr_t)v + v->vd_next):NULL; |
| 1978 | + |
| 1979 | + if (strtab && verdef && verdef_cnt) { |
| 1980 | + eh_find_sym(obj, s->name, &s->addr); |
| 1981 | + if (s->addr) { |
| 1982 | + eh_destroy_obj(obj); |
| 1983 | + return 1; |
1990 | 1984 | } |
1991 | 1985 | } |
1992 | 1986 | } |
1993 | 1987 | } |
| 1988 | + |
| 1989 | + eh_destroy_obj(obj); |
1994 | 1990 | return 0; |
1995 | 1991 | } |
1996 | 1992 |
|
1997 | 1993 | void* GetNativeSymbolUnversioned(void* lib, const char* name) |
1998 | 1994 | { |
1999 | | - // try to find "name" in loaded elf, whithout checking for the symbol version (like dlsym, but no version check) |
2000 | 1995 | search_symbol_t s; |
2001 | 1996 | s.name = name; |
2002 | 1997 | s.addr = NULL; |
2003 | | - if(lib) |
2004 | | - s.lib = lib; |
2005 | | - else |
2006 | | - s.lib = my_context->box64lib; |
2007 | | - printf_log(LOG_INFO, "Look for %s in loaded elfs\n", name); |
2008 | | - dl_iterate_phdr(dl_iterate_phdr_findsymbol, &s); |
| 1998 | + eh_iterate_obj((eh_iterate_obj_callback_func)dl_iterate_phdr_findsymbol, &s); |
2009 | 1999 | return s.addr; |
2010 | 2000 | } |
2011 | 2001 |
|
|
0 commit comments