#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <assert.h>
#include "debug.h"
#include "librarian.h"
#include "librarian_private.h"
#include "library.h"
#include "library_private.h"
#include "x64emu.h"
#include "box64context.h"
#include "elfloader.h"
#include "bridge.h"
KHASH_MAP_IMPL_INT(mapoffsets, cstr_t);
lib_t *NewLibrarian(box64context_t* context)
{
lib_t *maplib = (lib_t*)box_calloc(1, sizeof(lib_t));
maplib->mapoffsets = kh_init(mapoffsets);
maplib->globaldata = NewMapSymbols();
return maplib;
}
void FreeLibrarian(lib_t **maplib, x64emu_t *emu)
{
if(!maplib || !*maplib)
return;
library_t* owner = (*maplib)->owner;
(*maplib)->owner = NULL;
printf_dump(LOG_DEBUG, "Unloading %s\n", (*maplib)->libraries[i]->name);
DecRefCount(&(*maplib)->libraries[i], emu);
}*/
box_free((*maplib)->libraries);
(*maplib)->libraries = NULL;
if((*maplib)->mapoffsets) {
kh_destroy(mapoffsets, (*maplib)->mapoffsets);
}
FreeMapSymbols(&(*maplib)->globaldata);
(*maplib)->libsz = (*maplib)->libcap = 0;
box_free(*maplib);
*maplib = NULL;
}
box64context_t* GetLibrarianContext(lib_t* maplib)
{
return my_context;
}
kh_mapsymbols_t* GetGlobalData(lib_t* maplib)
{
return maplib->globaldata;
}
library_t* getLib(lib_t* maplib, const char* path)
{
for(int i=0; i<maplib->libsz; ++i) {
library_t *lib = maplib->libraries[i];
if(IsSameLib(lib, path)) {
return lib;
}
}
return NULL;
}
static int libraryInMapLib(lib_t* maplib, library_t* lib)
{
if(!maplib)
return 0;
for(int i=0; i<maplib->libsz; ++i)
if(maplib->libraries[i]==lib)
return 1;
return 0;
}
void MapLibAddLib(lib_t* maplib, library_t* lib)
{
if(libraryInMapLib(maplib, lib))
return;
if (maplib->libsz == maplib->libcap) {
maplib->libcap += 8;
maplib->libraries = (library_t**)box_realloc(maplib->libraries, maplib->libcap*sizeof(library_t*));
}
maplib->libraries[maplib->libsz] = lib;
++maplib->libsz;
}
void MapLibPrependLib(lib_t* maplib, library_t* lib, library_t* ref)
{
if(libraryInMapLib(maplib, lib))
return;
if (maplib->libsz == maplib->libcap) {
maplib->libcap += 8;
maplib->libraries = (library_t**)box_realloc(maplib->libraries, maplib->libcap*sizeof(library_t*));
}
int point = ref?maplib->libsz:0;
if(ref)
for(int i=0; i<maplib->libsz; ++i)
if(maplib->libraries[i]==ref) {
point = i;
i = maplib->libsz;
}
if(point<maplib->libsz)
memmove(&maplib->libraries[point+1], &maplib->libraries[point], sizeof(library_t*)*(maplib->libsz-point));
maplib->libraries[point] = lib;
++maplib->libsz;
}
static void MapLibAddMapLib(lib_t* dest, library_t* lib_src, lib_t* src)
{
if(!src)
return;
library_t *owner = src->owner;
for(int i=0; i<src->libsz; ++i) {
library_t* lib = src->libraries[i];
if(!lib || libraryInMapLib(dest, lib)) continue;
MapLibAddLib(dest, lib);
}
if(lib_src == owner)
FreeLibrarian(&src, NULL);
}
void MapLibRemoveLib(lib_t* maplib, library_t* lib)
{
if(!maplib || !lib)
return;
int idx = 0;
while(idx<maplib->libsz && maplib->libraries[idx]!=lib) ++idx;
if(idx==maplib->libsz)
return;
--maplib->libsz;
if(idx!=(maplib->libsz))
memmove(&maplib->libraries[idx], &maplib->libraries[idx+1], sizeof(library_t*)*(maplib->libsz-idx));
maplib->libraries[maplib->libsz] = NULL;
}
static void MapLibRemoveMapLib(lib_t* dest, lib_t* src)
{
if(!src)
return;
for(int i=0; i<src->libsz; ++i) {
library_t* lib = src->libraries[i];
if(!lib || !libraryInMapLib(dest, lib)) continue;
MapLibRemoveLib(dest, lib);
if(lib->maplib && src!=lib->maplib && dest!=lib->maplib) {
MapLibRemoveMapLib(dest, lib->maplib);
if(lib->maplib && src==my_context->local_maplib)
lib->maplib = NULL;
}
}
}
void promoteLocalLibGlobal(library_t* lib)
{
if(!lib || !my_context)
return;
if(lib->maplib && !lib->maplib_ref) {
lib_t* maplib = lib->maplib;
lib->maplib = NULL;
MapLibAddMapLib(my_context->maplib, lib, maplib);
}
lib->maplib = NULL;
lib->maplib_ref = 0;
if(!libraryInMapLib(my_context->maplib, lib))
MapLibAddLib(my_context->maplib, lib);
MapLibRemoveMapLib(my_context->local_maplib, my_context->maplib);
}
int isLibLocal(library_t* lib)
{
if(!lib || !my_context)
return 0;
return libraryInMapLib(my_context->local_maplib, lib);
}
static int AddNeededLib_add(lib_t** maplib, int local, needed_libs_t* needed, int n, elfheader_t* verneeded, box64context_t* box64, x64emu_t* emu)
{
const char* path = needed->names[n];
printf_dump(LOG_DEBUG, "Trying to add \"%s\" to maplib%s\n", path, local?" (local)":"");
library_t *lib = getLib(my_context->maplib, path);
if(lib) {
IncRefCount(lib, emu);
needed->libs[n] = lib;
if(local && *maplib)
MapLibAddLib(*maplib, lib);
printf_dump(LOG_DEBUG, "Already present in maplib => success\n");
return 0;
}
lib = getLib(my_context->local_maplib, path);
if(lib) {
printf_dump(LOG_DEBUG, "Already present in local_maplib => success\n");
needed->libs[n] = lib;
IncRefCount(lib, emu);
if(local) {
if(*maplib) {
MapLibAddLib(*maplib, lib);
}
} else {
promoteLocalLibGlobal(lib);
}
return 0;
}
needed->libs[n] = lib = NewLibrary(path, box64, verneeded);
if(!lib) {
printf_dump(LOG_DEBUG, "Faillure to create lib => fail\n");
return 1;
}
if(local) {
MapLibAddLib(my_context->local_maplib, lib);
if(*maplib) {
MapLibAddLib(*maplib, lib);
} else {
lib->maplib = NewLibrarian(box64);
MapLibAddLib(lib->maplib, lib);
}
} else {
MapLibAddLib(my_context->maplib, lib);
}
if(!*maplib)
*maplib = (local)?lib->maplib:my_context->maplib;
if(local && !lib->maplib) {
lib->maplib = *maplib;
lib->maplib_ref = 1;
}
if(AddSymbolsLibrary(*maplib, lib, emu)) {
printf_dump(LOG_DEBUG, "Failure to Add lib => fail\n");
return 1;
}
if (lib->type == LIB_EMULATED) {
linkmap_t *lm = addLinkMapLib(lib);
if(!lm) {
printf_dump(LOG_DEBUG, "Failure to add lib linkmap\n");
return 1;
}
lm->l_addr = (Elf64_Addr)GetElfDelta(lib->e.elf);
lm->l_name = lib->name;
lm->l_ld = GetDynamicSection(lib->e.elf);
}
IncRefCount(lib, emu);
return 0;
}
int AddNeededLib_init(lib_t* maplib, int local, int bindnow, int deepbind, library_t* lib, elfheader_t* verneeded, box64context_t* box64, x64emu_t* emu)
{
if(!lib)
return 0;
if(!maplib)
maplib = (local)?lib->maplib:my_context->maplib;
elfheader_t* mainelf = GetElf(lib);
if(!mainelf) {
} else {
if(LoadNeededLibs(mainelf, maplib, local, bindnow, deepbind, box64, emu)) {
printf_dump(LOG_DEBUG, "Failure to Add dependant lib => fail\n");
return 1;
}
if(FinalizeLibrary(lib, local?maplib:NULL, bindnow, deepbind, emu)) {
printf_dump(LOG_DEBUG, "Failure to finalizing lib => fail\n");
return 1;
}
}
printf_dump(LOG_DEBUG, "Created lib and added to maplib => success\n");
return 0;
}
void AddNeededLib_remove(lib_t* maplib, int local, library_t** lib, box64context_t* box64, x64emu_t* emu)
{
if(!lib || !*lib)
return;
if(!maplib)
maplib = (local)?(*lib)->maplib:my_context->maplib;
DecRefCount(lib, emu);
}
EXPORTDYN
int AddNeededLib(lib_t* maplib, int local, int bindnow, int deepbind, needed_libs_t* needed, elfheader_t* verneeded, box64context_t* box64, x64emu_t* emu)
{
if(!needed)
return 0;
box64_mapclean = 0;
int ret = 0;
for(int i=0; i<needed->size; ++i) {
if(AddNeededLib_add(&maplib, local, needed, i, verneeded, box64, emu)) {
printf_log(strchr(needed->names[i],'/')?LOG_DEBUG:LOG_INFO, "Error loading needed lib %s\n", needed->names[i]);
ret = 1;
}
}
if(ret) {
return ret;
}
int n = needed->size;
for (int i=0; i<n; ++i)
if(AddNeededLib_init(maplib, local, bindnow, deepbind, needed->libs[n-i-1], verneeded, box64, emu)) {
printf_log(LOG_INFO, "Error initializing needed lib %s\n", needed->names[i]);
ret = 1;
}
if(ret) {
int n = needed->size;
for (int i=0; i<n; ++i)
DecRefCount(&needed->libs[n-i-1], emu);
}
if(allow_missing_libs) return 0;
return ret;
}
EXPORTDYN
void RemoveNeededLib(lib_t* maplib, int local, needed_libs_t* needed, box64context_t* box64, x64emu_t* emu)
{
if(!needed)
return;
for(int i=0; i<needed->size; ++i) {
if(box64_log>=LOG_DEBUG && needed->libs[i])
printf_dump(LOG_DEBUG, "Will remove after failed init %s\n", needed->names[i]);
AddNeededLib_remove(maplib, local, &needed->libs[i], box64, emu);
}
}
library_t* GetLibMapLib(lib_t* maplib, const char* name)
{
printf_dump(LOG_DEBUG, "Trying to Get \"%s\" to maplib\n", name);
return getLib(maplib, name);
}
library_t* GetLibInternal(const char* name)
{
printf_dump(LOG_DEBUG, "Trying to Get \"%s\" to maplib\n", name);
library_t* lib = getLib(my_context->maplib, name);
if(!lib) lib = getLib(my_context->local_maplib, name);
return lib;
}
EXPORTDYN
uintptr_t FindGlobalSymbol(lib_t *maplib, const char* name, int version, const char* vername, int veropt)
{
uintptr_t start = 0, end = 0;
if(GetGlobalSymbolStartEnd(maplib, name, &start, &end, (void*)1, version, vername, veropt, NULL))
return start;
return 0;
}
static int isLocal(elfheader_t* self, library_t* l)
{
if(GetElf(l)==self)
return 1;
return 0;
}
static void CheckNeededLibs(needed_libs_t* needed)
{
while(needed->nb_done<needed->size) {
library_t* lib = needed->libs[needed->nb_done++];
if(lib) {
int n = GetNeededLibsN(lib);
char** names = GetNeededLibsNames(lib);
for (int i=0; i<n; ++i) {
add1lib_neededlib(needed, GetNeededLib(lib, i), names[i]);
}
}
}
}
int GetNoSelfSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, uintptr_t* end, elfheader_t* self, size_t size, int version, const char* vername, int veropt, void** elfsym)
{
assert(self);
int weak = 0;
void* sym;
if(my_context->preload)
for(int i=0; i<my_context->preload->size; ++i)
if(self!=GetElf(my_context->preload->libs[i]) && GetLibGlobalSymbolStartEnd(my_context->preload->libs[i], name, start, end, size, &weak, &version, &vername, 0, &veropt, elfsym)) {
return 1;
}
if(maplib==my_context->maplib) {
if(self!=my_context->elfs[0] && (sym = ElfGetGlobalSymbolStartEnd(my_context->elfs[0], start, end, name, &version, &vername, 0, &veropt))) {
if(elfsym) *elfsym = sym;
return 1;
}
}
if(maplib) {
for(int i=0; i<maplib->libsz; ++i) {
if(self!=GetElf(maplib->libraries[i]) && GetLibGlobalSymbolStartEnd(maplib->libraries[i], name, start, end, size, &weak, &version, &vername, 0, &veropt, elfsym))
return 1;
}
}
if(self!=my_context->elfs[0] && (sym = ElfGetWeakSymbolStartEnd(my_context->elfs[0], start, end, name, &version, &vername, 0, &veropt))) {
if(elfsym) *elfsym = sym;
weak = 1;
}
if(maplib)
for(int i=0; i<maplib->libsz; ++i) {
if(self!=GetElf(maplib->libraries[i]) && GetLibWeakSymbolStartEnd(maplib->libraries[i], name, start, end, size, &weak, &version, &vername, 0, &veropt, elfsym)) {
weak = 1;
}
}
return weak;
}
static int GetGlobalSymbolStartEnd_internal(lib_t *maplib, const char* name, uintptr_t* start, uintptr_t* end, elfheader_t* self, int* version, const char** vername, int* veropt, void** elfsym)
{
int weak = 0;
size_t size = 0;
void* sym;
if(my_context->preload)
for(int i=0; i<my_context->preload->size; ++i)
if(GetLibGlobalSymbolStartEnd(my_context->preload->libs[i], name, start, end, size, &weak, version, vername, isLocal(self, my_context->preload->libs[i]), veropt, elfsym)) {
return 1;
}
if(maplib==my_context->maplib) {
if((sym = ElfGetGlobalSymbolStartEnd(my_context->elfs[0], start, end, name, version, vername, (my_context->elfs[0]==self || !self)?1:0, veropt))) {
if(elfsym) *elfsym = sym;
return 1;
}
}
if(maplib) {
for(int i=0; i<maplib->libsz; ++i) {
if(GetLibGlobalSymbolStartEnd(maplib->libraries[i], name, start, end, size, &weak, version, vername, isLocal(self, maplib->libraries[i]), veropt, elfsym))
return 1;
}
}
if((sym = ElfGetWeakSymbolStartEnd(my_context->elfs[0], start, end, name, version, vername, (my_context->elfs[0]==self || !self)?1:0, veropt))) {
if(elfsym) *elfsym = sym;
weak = 1;
}
if(maplib)
for(int i=0; i<maplib->libsz; ++i) {
if(GetLibWeakSymbolStartEnd(maplib->libraries[i], name, start, end, size, &weak, version, vername, isLocal(self, maplib->libraries[i]), veropt, elfsym)) {
weak = 1;
}
}
return weak;
}
#ifndef STATICBUILD
void** my_GetGTKDisplay();
void** my_GetGthreadsGotInitialized();
#endif
int GetGlobalSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, uintptr_t* end, elfheader_t* self, int version, const char* vername, int veropt, void** elfsym)
{
if(GetGlobalSymbolStartEnd_internal(maplib, name, start, end, self, &version, &vername, &veropt, elfsym)) {
if(start && end && *end==*start) {
uintptr_t start2, end2;
char* buff = (char*)malloc(strlen(name) + strlen("_END") + 1);
strcpy(buff, name);
strcat(buff, "_END");
if(GetGlobalSymbolStartEnd_internal(maplib, buff, &start2, &end2, self, &version, &vername, &veropt, elfsym)) {
if(end2>*end && start2==end2)
*end = end2;
}
box_free(buff);
}
return 1;
}
#ifndef STATICBUILD
if(!strcmp(name, "gdk_display") && !box64_nogtk) {
*start = (uintptr_t)my_GetGTKDisplay();
*end = *start+sizeof(void*);
printf_log(LOG_INFO, "Using global gdk_display for gdk-x11 (%p:%p)\n", start, *(void**)start);
return 1;
}
if(!strcmp(name, "g_threads_got_initialized") && !box64_nogtk) {
*start = (uintptr_t)my_GetGthreadsGotInitialized();
*end = *start+sizeof(int);
printf_log(LOG_INFO, "Using global g_threads_got_initialized for gthread2 (%p:%p)\n", start, *(void**)start);
return 1;
}
#endif
return 0;
}
static int GetGlobalWeakSymbolStartEnd_internal(lib_t *maplib, const char* name, uintptr_t* start, uintptr_t* end, elfheader_t* self, int* version, const char** vername, int* veropt, void** elfsym)
{
int weak = 0;
size_t size = 0;
void* sym;
if(my_context->preload)
for(int i=0; i<my_context->preload->size; ++i)
if(GetLibGlobalSymbolStartEnd(my_context->preload->libs[i], name, start, end, size, &weak, version, vername, isLocal(self, my_context->preload->libs[i]), veropt, elfsym))
return 1;
if((sym = ElfGetGlobalSymbolStartEnd(my_context->elfs[0], start, end, name, version, vername, (my_context->elfs[0]==self || !self)?1:0, veropt))) {
if(elfsym) *elfsym = sym;
return 1;
}
if(maplib)
for(int i=0; i<maplib->libsz; ++i) {
if(GetLibGlobalSymbolStartEnd(maplib->libraries[i], name, start, end, size, &weak, version, vername, isLocal(self, maplib->libraries[i]), veropt, elfsym))
return 1;
}
int ok = 0;
if(( sym = ElfGetWeakSymbolStartEnd(my_context->elfs[0], start, end, name, version, vername, (my_context->elfs[0]==self || !self)?1:0, veropt))) {
if(elfsym) *elfsym = sym;
ok = 1;
}
if(maplib)
for(int i=0; i<maplib->libsz; ++i) {
if(GetLibWeakSymbolStartEnd(maplib->libraries[i], name, start, end, size, &weak, version, vername, isLocal(self, maplib->libraries[i]), veropt, elfsym))
ok = 1;
}
return ok;
}
int GetGlobalWeakSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, uintptr_t* end, elfheader_t* self, int version, const char* vername, int veropt, void** elfsym)
{
if(GetGlobalWeakSymbolStartEnd_internal(maplib, name, start, end, self, &version, &vername, &veropt, elfsym)) {
if(start && end && *end==*start) {
uintptr_t start2, end2;
char* buff = (char*)malloc(strlen(name) + strlen("_END") + 1);
strcpy(buff, name);
strcat(buff, "_END");
if(GetGlobalWeakSymbolStartEnd_internal(maplib, buff, &start2, &end2, self, &version, &vername, &veropt, elfsym)) {
if(end2>*end && start2==end2)
*end = end2;
}
box_free(buff);
}
return 1;
}
#ifndef STATICBUILD
if(!strcmp(name, "gdk_display") && !box64_nogtk) {
*start = (uintptr_t)my_GetGTKDisplay();
*end = *start+sizeof(void*);
if(elfsym) *elfsym = NULL;
printf_log(LOG_INFO, "Using global gdk_display for gdk-x11 (%p:%p)\n", start, *(void**)start);
return 1;
}
if(!strcmp(name, "g_threads_got_initialized") && !box64_nogtk) {
*start = (uintptr_t)my_GetGthreadsGotInitialized();
*end = *start+sizeof(int);
if(elfsym) *elfsym = NULL;
printf_log(LOG_INFO, "Using global g_threads_got_initialized for gthread2 (%p:%p)\n", start, *(void**)start);
return 1;
}
#endif
return 0;
}
elfheader_t* GetGlobalSymbolElf(lib_t *maplib, const char* name, int version, const char* vername, int veropt)
{
uintptr_t start = 0;
uintptr_t end = 0;
size_t size = 0;
int weak = 0;
elfheader_t* ret = NULL;
if(ElfGetGlobalSymbolStartEnd(my_context->elfs[0], &start, &end, name, &version, &vername, 1, &veropt))
return my_context->elfs[0];
for(int i=0; i<maplib->libsz; ++i) {
if(GetLibGlobalSymbolStartEnd(maplib->libraries[i], name, &start, &end, size, &weak, &version, &vername, 1, &veropt, NULL)) {
elfheader_t* h = GetElf(maplib->libraries[i]);
if(!h) {
printf_log(LOG_NONE, "Warning, getting Elf info for a native symbol \"%s\" from lib \"%s\"\n", name, GetNameLib(maplib->libraries[i]));
return NULL;
}
if(weak)
ret = h;
else
return h;
}
}
if(ElfGetWeakSymbolStartEnd(my_context->elfs[0], &start, &end, name, &version, &vername, 1, &veropt))
ret = my_context->elfs[0];
for(int i=0; i<maplib->libsz; ++i) {
if(GetLibWeakSymbolStartEnd(maplib->libraries[i], name, &start, &end, size, &weak, &version, &vername, 1, &veropt, NULL)) {
elfheader_t* h = GetElf(maplib->libraries[i]);
if(!h) {
printf_log(LOG_NONE, "Warning, getting Elf info for a native symbol \"%s\" from lib \"%s\"\n", name, GetNameLib(maplib->libraries[i]));
return NULL;
}
if(weak)
ret = h;
else
return h;
}
}
return ret;
}
int GetGlobalNoWeakSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, uintptr_t* end, int version, const char* vername, int veropt, void** elfsym)
{
int weak = 0;
size_t size = 0;
void* sym;
if(GetSymbolStartEnd(GetGlobalData(maplib), name, start, end, version, vername, 1, veropt)) {
if(elfsym) *elfsym = NULL;
return 1;
}
if((sym = ElfGetGlobalSymbolStartEnd(my_context->elfs[0], start, end, name, &version, &vername, 1, &veropt))) {
if(elfsym) *elfsym = sym;
return 1;
}
for(int i=0; i<maplib->libsz; ++i)
if(GetLibGlobalSymbolStartEnd(maplib->libraries[i], name, start, end, size, &weak, &version, &vername, 1, &veropt, elfsym))
return 1;
return 0;
}
int IsGlobalNoWeakSymbolInNative(lib_t *maplib, const char* name, int version, const char* vername, int veropt)
{
uintptr_t start, end;
size_t size = 0;
int weak;
for(int i=0; i<maplib->libsz; ++i)
if(GetElfIndex(maplib->libraries[i])==-1)
if(GetLibGlobalSymbolStartEnd(maplib->libraries[i], name, &start, &end, size, &weak, &version, &vername, 1, &veropt, NULL))
return 1;
return 0;
}
int GetLocalSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, uintptr_t* end, elfheader_t *self, int version, const char* vername, int veropt, void** elfsym)
{
int weak;
size_t size = 0;
void* sym;
if(my_context->elfs[0]==self || !self) {
if((sym = ElfGetLocalSymbolStartEnd(my_context->elfs[0], start, end, name, &version, &vername, 1, &veropt))) {
if(elfsym) *elfsym = sym;
return 1;
}
if(self)
return 0;
}
for(int i=0; i<maplib->libsz; ++i) {
if(GetElfIndex(maplib->libraries[i])!=-1 && (!self || GetElf(maplib->libraries[i])==self)) {
if(GetLibLocalSymbolStartEnd(maplib->libraries[i], name, start, end, size, &weak, &version, &vername, 1, &veropt, elfsym))
return 1;
if(self)
return 0;
}
}
return 0;
}
int GetSymTabStartEnd(lib_t* maplib, const char* name, uintptr_t* start, uintptr_t* end)
{
if(!maplib)
return 0;
for(int i=0; i<maplib->libsz; ++i) {
elfheader_t* h = GetElf(maplib->libraries[i]);
if(h && ElfGetSymTabStartEnd(h, start, end, name))
return 1;
}
return 0;
}
const char* FindSymbolName(lib_t *maplib, void* p, void** start, uint64_t* sz, const char** libname, void** base, library_t** lib)
{
const char* ret = NULL;
uintptr_t offs = 0;
uint64_t size = 0;
elfheader_t* h = FindElfAddress(my_context, (uintptr_t)p);
if(h) {
ret = FindNearestSymbolName(h, p, &offs, &size);
if(start)
*start = (void*)offs;
if(sz)
*sz = size;
if(libname)
*libname = ElfName(h);
if(base)
*base = GetBaseAddress(h);
if(lib) {
if(h == my_context->elfs[0])
*lib = NULL;
else {
for(int i=0; i<my_context->maplib->libsz; ++i) {
elfheader_t* head = GetElf(my_context->maplib->libraries[i]);
if((head) && (head==h)) {
*lib = my_context->maplib->libraries[i];
return ret;
}
}
for(int i=0; i<my_context->local_maplib->libsz; ++i) {
elfheader_t* head = GetElf(my_context->local_maplib->libraries[i]);
if((head) && (head==h)) {
*lib = my_context->local_maplib->libraries[i];
return ret;
}
}
}
}
return ret;
}
// if (maplib == maplib->libraries[i]->maplib) continue;
const char *nameInLib = FindSymbolName(maplib->libraries[i]->maplib, p, start, sz, libname, base);
if (nameInLib) return nameInLib;
} */
return NULL;
}
void AddOffsetSymbol(lib_t *maplib, void* offs, const char* name)
{
int ret;
khint_t k = kh_put(mapoffsets, maplib->mapoffsets, (uintptr_t)offs, &ret);
kh_value(maplib->mapoffsets, k) = (cstr_t)name;
}
const char* GetNameOffset(lib_t *maplib, void* offs)
{
if(!maplib || !maplib->mapoffsets)
return NULL;
khint_t k = kh_get(mapoffsets, maplib->mapoffsets, (uintptr_t)offs);
if (k!=kh_end(maplib->mapoffsets))
return kh_value(maplib->mapoffsets, k);
return NULL;
}