diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2022-10-22 20:57:31 +0200 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2022-10-22 20:57:31 +0200 |
| commit | 58cdb1bda2f2dd6a0bc5ea42e99b279fc687c06b (patch) | |
| tree | 099bf5dc7d814272d6842df6656c2e672d5a1143 /src/librarian/library.c | |
| parent | a530f565110875c431ff9600ee9da4a640599ec7 (diff) | |
| download | box64-58cdb1bda2f2dd6a0bc5ea42e99b279fc687c06b.tar.gz box64-58cdb1bda2f2dd6a0bc5ea42e99b279fc687c06b.zip | |
Refactored, again, elfloader symbol fetching (ported from box86)
Diffstat (limited to 'src/librarian/library.c')
| -rwxr-xr-x | src/librarian/library.c | 280 |
1 files changed, 194 insertions, 86 deletions
diff --git a/src/librarian/library.c b/src/librarian/library.c index 50fd6df2..77a8d3a9 100755 --- a/src/librarian/library.c +++ b/src/librarian/library.c @@ -24,17 +24,20 @@ #include "librarian_private.h" #include "pathcoll.h" #include "x64emu.h" +#include "symbols.h" +#include "elfs/elfloader_private.h" +#include "library_inner.h" #include "wrappedlibs.h" // create the native lib list #define GO(P, N) int wrapped##N##_init(library_t* lib, box64context_t *box64); \ - void wrapped##N##_fini(library_t* lib); \ - int wrapped##N##_get(library_t* lib, const char* name, uintptr_t *offs, uintptr_t *sz, int version, const char* vername, int local); \ - int wrapped##N##_getnoweak(library_t* lib, const char* name, uintptr_t *offs, uintptr_t *sz, int version, const char* vername, int local); + void wrapped##N##_fini(library_t* lib); + #include "library_list.h" + #undef GO -#define GO(P, N) {P, wrapped##N##_init, wrapped##N##_fini, wrapped##N##_get, wrapped##N##_getnoweak}, +#define GO(P, N) {P, wrapped##N##_init, wrapped##N##_fini}, wrappedlib_t wrappedlibs[] = { #include "library_list.h" }; @@ -81,7 +84,7 @@ int NbDot(const char* name) return ret; } -void NativeLib_CommonInit(library_t *lib) { +void WrappedLib_CommonInit(library_t *lib) { lib->w.bridge = NewBridge(); lib->w.symbolmap = kh_init(symbolmap); @@ -97,10 +100,8 @@ void NativeLib_CommonInit(library_t *lib) { void EmuLib_Fini(library_t* lib) { - kh_destroy(mapsymbols, lib->e.mapsymbols); - kh_destroy(mapsymbols, lib->e.localsymbols); } -void NativeLib_FinishFini(library_t* lib) +void WrappedLib_FinishFini(library_t* lib) { if(lib->w.lib) dlclose(lib->w.lib); @@ -117,79 +118,88 @@ void NativeLib_FinishFini(library_t* lib) FreeBridge(&lib->w.bridge); } -int WrappedLib_defget(library_t* lib, const char* name, uintptr_t *offs, uintptr_t *sz, int version, const char* vername, int local) { +int WrappedLib_GetWeak(library_t* lib, const char* name, uintptr_t *offs, uintptr_t *sz, int* weak, int version, const char* vername, int local) { uintptr_t addr = 0; uintptr_t size = 0; - if (!getSymbolInMaps(lib, name, 0, &addr, &size, version, vername, local)) { + int wk = 0; + if (!getSymbolInMaps(lib, name, 0, &addr, &size, &wk, version, vername, local)) { return 0; } if(!addr && !size) return 0; + if(!wk) // found a global symbol + return 0; *offs = addr; *sz = size; + *weak = wk; return 1; } -int EmuLib_Get(library_t* lib, const char* name, uintptr_t *offs, uintptr_t *sz, int version, const char* vername, int local) +int EmuLib_GetWeak(library_t* lib, const char* name, uintptr_t *offs, uintptr_t *sz, int*weak, int version, const char* vername, int local) { // symbols... uintptr_t start, end; - if(GetSymbolStartEnd(lib->e.mapsymbols, name, &start, &end, version, vername, local)) - { - *offs = start; - *sz = end-start; - return 1; - } + const char* defver = GetDefaultVersion(my_context->weakdefver, name); // weak symbols... - if(GetSymbolStartEnd(lib->e.weaksymbols, name, &start, &end, version, vername, local)) + if(GetSymbolStartEnd(GetWeakSymbols(lib->e.elf), name, &start, &end, version, vername, local, defver)) { *offs = start; *sz = end-start; + *weak = 1; return 1; } return 0; } -int WrappedLib_defgetnoweak(library_t* lib, const char* name, uintptr_t *offs, uintptr_t *sz, int version, const char* vername, int local) { +int WrappedLib_GetGlobal(library_t* lib, const char* name, uintptr_t *offs, uintptr_t *sz, int* weak, int version, const char* vername, int local) { uintptr_t addr = 0; uintptr_t size = 0; - if (!getSymbolInMaps(lib, name, 1, &addr, &size, version, vername, local)) { + int wk = 0; + if (!getSymbolInMaps(lib, name, 1, &addr, &size, &wk, version, vername, local)) { return 0; } if(!addr && !size) return 0; + if(wk) + return 0; //found a weak symbol *offs = addr; *sz = size; + *weak = 0; return 1; } -int EmuLib_GetNoWeak(library_t* lib, const char* name, uintptr_t *offs, uintptr_t *sz, int version, const char* vername, int local) +int EmuLib_GetGlobal(library_t* lib, const char* name, uintptr_t *offs, uintptr_t *sz, int* weak, int version, const char* vername, int local) { uintptr_t start, end; - if(GetSymbolStartEnd(lib->e.mapsymbols, name, &start, &end, version, vername, local)) + const char* defver = GetDefaultVersion(my_context->globaldefver, name); + if(GetSymbolStartEnd(GetMapSymbols(lib->e.elf), name, &start, &end, version, vername, local, defver)) { *offs = start; *sz = end-start; + *weak = 0; return 1; } return 0; } -int EmuLib_GetLocal(library_t* lib, const char* name, uintptr_t *offs, uintptr_t *sz, int version, const char* vername, int local) +int EmuLib_GetLocal(library_t* lib, const char* name, uintptr_t *offs, uintptr_t *sz, int* weak, int version, const char* vername, int local) { uintptr_t start, end; - if(GetSymbolStartEnd(lib->e.localsymbols, name, &start, &end, version, vername, local)) + const char* defver = GetDefaultVersion(my_context->globaldefver, name); + if(!defver) defver = GetDefaultVersion(my_context->weakdefver, name); + if(GetSymbolStartEnd(GetLocalSymbols(lib->e.elf), name, &start, &end, version, vername, local, defver)) { *offs = start; *sz = end-start; + *weak = 0; return 1; } return 0; } -int NativeLib_GetLocal(library_t* lib, const char* name, uintptr_t *offs, uintptr_t *sz, int version, const char* vername, int local) +int WrappedLib_GetLocal(library_t* lib, const char* name, uintptr_t *offs, uintptr_t *sz, int* weak, int version, const char* vername, int local) { (void)lib; (void)name; (void)offs; (void)sz; (void)version; (void)vername; (void)local; return 0; } -static void initNativeLib(library_t *lib, box64context_t* context) { +static void initWrappedLib(library_t *lib, box64context_t* context) { int nb = sizeof(wrappedlibs) / sizeof(wrappedlib_t); for (int i=0; i<nb; ++i) { if(strcmp(lib->name, wrappedlibs[i].name)==0) { @@ -202,10 +212,10 @@ static void initNativeLib(library_t *lib, box64context_t* context) { } printf_log(LOG_INFO, "Using native(wrapped) %s\n", lib->name); lib->fini = wrappedlibs[i].fini; - lib->get = wrappedlibs[i].get; - lib->getnoweak = wrappedlibs[i].getnoweak; - lib->getlocal = NativeLib_GetLocal; - lib->type = LIB_NATIVE; + lib->getglobal = WrappedLib_GetGlobal; + lib->getweak = WrappedLib_GetWeak; + lib->getlocal = WrappedLib_GetLocal; + lib->type = LIB_WRAPPED; // Call librarian to load all dependant elf if(AddNeededLib(context->maplib, &lib->needed, lib, 0, 0, (const char**)lib->w.neededlibs, lib->w.needed, context, thread_get_emu())) { printf_log(LOG_NONE, "Error: loading a needed libs in elf %s\n", lib->name); @@ -271,14 +281,11 @@ static int loadEmulatedLib(const char* libname, library_t *lib, box64context_t* lib->type = LIB_EMULATED; lib->fini = EmuLib_Fini; - lib->get = EmuLib_Get; - lib->getnoweak = EmuLib_GetNoWeak; + lib->getglobal = EmuLib_GetGlobal; + lib->getweak = EmuLib_GetWeak; lib->getlocal = EmuLib_GetLocal; lib->e.elf_index = mainelf; lib->e.elf = elf_header; - lib->e.mapsymbols = kh_init(mapsymbols); - lib->e.weaksymbols = kh_init(mapsymbols); - lib->e.localsymbols = kh_init(mapsymbols); if(lib->path && strcmp(lib->path, libname)) { box_free(lib->path); @@ -381,13 +388,13 @@ library_t *NewLibrary(const char* path, box64context_t* context) // And now, actually loading a library // look for native(wrapped) libs first if(!notwrapped && !precise) - initNativeLib(lib, context); + initWrappedLib(lib, context); // then look for a native one if(lib->type==LIB_UNNKNOW) initEmulatedLib(path, lib, context); // still not loaded but notwrapped indicated: use wrapped... if(lib->type==LIB_UNNKNOW && notwrapped && !precise) - initNativeLib(lib, context); + initWrappedLib(lib, context); // nothing loaded, so error... if(lib->type==LIB_UNNKNOW) { @@ -396,7 +403,9 @@ library_t *NewLibrary(const char* path, box64context_t* context) box_free(lib); return NULL; } - lib->bridgemap = kh_init(bridgemap); + lib->gbridgemap = kh_init(bridgemap); + lib->wbridgemap = kh_init(bridgemap); + lib->lbridgemap = kh_init(bridgemap); return lib; } @@ -408,7 +417,7 @@ int AddSymbolsLibrary(lib_t *maplib, library_t* lib, x64emu_t* emu) if(lib->type==LIB_EMULATED) { elfheader_t *elf_header = lib->e.elf; // add symbols - AddSymbols(maplib, lib->e.mapsymbols, lib->e.weaksymbols, lib->e.localsymbols, elf_header); + AddSymbols(maplib, GetMapSymbols(lib->e.elf), GetWeakSymbols(lib->e.elf), GetLocalSymbols(lib->e.elf), elf_header); } return 0; } @@ -432,12 +441,13 @@ int FinalizeLibrary(library_t* lib, lib_t* local_maplib, int bindnow, x64emu_t* } #ifdef HAVE_TRACE if(trace_func) { + int weak; if (GetGlobalSymbolStartEnd(local_maplib, trace_func, &trace_start, &trace_end, elf_header, -1, NULL)) { SetTraceEmu(trace_start, trace_end); printf_log(LOG_INFO, "TRACE on %s only (%p-%p)\n", trace_func, (void*)trace_start, (void*)trace_end); box_free(trace_func); trace_func = NULL; - } else if(GetLibLocalSymbolStartEnd(lib, trace_func, &trace_start, &trace_end, -1, NULL, 0)) { + } else if(GetLibLocalSymbolStartEnd(lib, trace_func, &trace_start, &trace_end, &weak, -1, NULL, 0)) { SetTraceEmu(trace_start, trace_end); printf_log(LOG_INFO, "TRACE on %s only (%p-%p)\n", trace_func, (void*)trace_start, (void*)trace_end); box_free(trace_func); @@ -518,14 +528,28 @@ void Free1Library(library_t **lib, x64emu_t* emu) box_free((*lib)->name); box_free((*lib)->path); - if((*lib)->bridgemap) { + if((*lib)->gbridgemap) { + bridged_t *br; + kh_foreach_value_ref((*lib)->gbridgemap, br, + free(br->name); + ); + kh_destroy(bridgemap, (*lib)->gbridgemap); + } + if((*lib)->wbridgemap) { bridged_t *br; - kh_foreach_value_ref((*lib)->bridgemap, br, - box_free(br->name); + kh_foreach_value_ref((*lib)->wbridgemap, br, + free(br->name); ); - kh_destroy(bridgemap, (*lib)->bridgemap); + kh_destroy(bridgemap, (*lib)->wbridgemap); } - if((*lib)->type == LIB_NATIVE) { + if((*lib)->lbridgemap) { + bridged_t *br; + kh_foreach_value_ref((*lib)->lbridgemap, br, + free(br->name); + ); + kh_destroy(bridgemap, (*lib)->lbridgemap); + } + if((*lib)->type == LIB_WRAPPED) { if((*lib)->w.symbolmap) kh_destroy(symbolmap, (*lib)->w.symbolmap); if((*lib)->w.wsymbolmap) @@ -546,7 +570,7 @@ void Free1Library(library_t **lib, x64emu_t* emu) kh_destroy(symbol2map, (*lib)->w.symbol2map); } free_neededlib(&(*lib)->needed); - free_neededlib(&(*lib)->depended); + free_neededlib(&(*lib)->dependedby); box_free(*lib); *lib = NULL; @@ -562,7 +586,7 @@ int IsSameLib(library_t* lib, const char* path) if(!lib) return 0; char* name = Path2Name(path); - if(!strchr(path, '/') || lib->type==LIB_NATIVE || !lib->path) { + if(!strchr(path, '/') || lib->type==LIB_WRAPPED || !lib->path) { if(strcmp(name, lib->name)==0) ret=1; } else { @@ -581,79 +605,91 @@ int IsSameLib(library_t* lib, const char* path) box_free(name); return ret; } -int GetLibSymbolStartEnd(library_t* lib, const char* name, uintptr_t* start, uintptr_t* end, int version, const char* vername, int local) +int GetLibWeakSymbolStartEnd(library_t* lib, const char* name, uintptr_t* start, uintptr_t* end, int* weak, int version, const char* vername, int local) { if(!name[0] || !lib->active) return 0; khint_t k; // check first if already in the map - k = kh_get(bridgemap, lib->bridgemap, VersionnedName(name, version, vername)); - if(k!=kh_end(lib->bridgemap)) { - *start = kh_value(lib->bridgemap, k).start; - *end = kh_value(lib->bridgemap, k).end; + k = kh_get(bridgemap, lib->wbridgemap, VersionnedName(name, version, vername)); + if(k!=kh_end(lib->wbridgemap)) { + *start = kh_value(lib->wbridgemap, k).start; + *end = kh_value(lib->wbridgemap, k).end; + *weak = 1; return 1; } + if(local) { + k = kh_get(bridgemap, lib->lbridgemap, VersionnedName(name, version, vername)); + if(k!=kh_end(lib->lbridgemap)) { + *start = kh_value(lib->lbridgemap, k).start; + *end = kh_value(lib->lbridgemap, k).end; + *weak = 0; + return 1; + } + } // get a new symbol - if(lib->get(lib, name, start, end, version, vername, local)) { + if(lib->getweak(lib, name, start, end, weak, version, vername, local)) { *end += *start; // lib->get(...) gives size, not end char* symbol = box_strdup(VersionnedName(name, version, vername)); int ret; - k = kh_put(bridgemap, lib->bridgemap, symbol, &ret); - kh_value(lib->bridgemap, k).name = symbol; - kh_value(lib->bridgemap, k).start = *start; - kh_value(lib->bridgemap, k).end = *end; + kh_bridgemap_t *map = local?lib->lbridgemap:((*weak)?lib->wbridgemap:lib->gbridgemap); + k = kh_put(bridgemap, map, symbol, &ret); + kh_value(map, k).name = symbol; + kh_value(map, k).start = *start; + kh_value(map, k).end = *end; return 1; } // nope return 0; } -int GetLibNoWeakSymbolStartEnd(library_t* lib, const char* name, uintptr_t* start, uintptr_t* end, int version, const char* vername, int local) +int GetLibGlobalSymbolStartEnd(library_t* lib, const char* name, uintptr_t* start, uintptr_t* end, int* weak, int version, const char* vername, int local) { if(!name[0] || !lib->active) return 0; khint_t k; // get a new symbol - if(lib->getnoweak(lib, name, start, end, version, vername, local)) { + if(lib->getglobal(lib, name, start, end, weak, version, vername, local)) { *end += *start; // lib->get(...) gives size, not end + kh_bridgemap_t *map = local?lib->lbridgemap:((*weak)?lib->wbridgemap:lib->gbridgemap); // check if already in the map - k = kh_get(bridgemap, lib->bridgemap, VersionnedName(name, version, vername)); - if(k!=kh_end(lib->bridgemap)) { - *start = kh_value(lib->bridgemap, k).start; - *end = kh_value(lib->bridgemap, k).end; + k = kh_get(bridgemap, map, VersionnedName(name, version, vername)); + if(k!=kh_end(map)) { + *start = kh_value(map, k).start; + *end = kh_value(map, k).end; return 1; } char* symbol = box_strdup(VersionnedName(name, version, vername)); int ret; - k = kh_put(bridgemap, lib->bridgemap, symbol, &ret); - kh_value(lib->bridgemap, k).name = symbol; - kh_value(lib->bridgemap, k).start = *start; - kh_value(lib->bridgemap, k).end = *end; + k = kh_put(bridgemap, map, symbol, &ret); + kh_value(map, k).name = symbol; + kh_value(map, k).start = *start; + kh_value(map, k).end = *end; return 1; } // nope return 0; } -int GetLibLocalSymbolStartEnd(library_t* lib, const char* name, uintptr_t* start, uintptr_t* end, int version, const char* vername, int local) +int GetLibLocalSymbolStartEnd(library_t* lib, const char* name, uintptr_t* start, uintptr_t* end, int* weak, int version, const char* vername, int local) { if(!name[0] || !lib->active) return 0; khint_t k; // check first if already in the map - k = kh_get(bridgemap, lib->bridgemap, VersionnedName(name, version, vername)); - if(k!=kh_end(lib->bridgemap)) { - *start = kh_value(lib->bridgemap, k).start; - *end = kh_value(lib->bridgemap, k).end; + k = kh_get(bridgemap, lib->lbridgemap, VersionnedName(name, version, vername)); + if(k!=kh_end(lib->lbridgemap)) { + *start = kh_value(lib->lbridgemap, k).start; + *end = kh_value(lib->lbridgemap, k).end; return 1; } // get a new symbol - if(lib->getlocal(lib, name, start, end, version, vername, local)) { + if(lib->getlocal(lib, name, start, end, weak, version, vername, local)) { *end += *start; // lib->get(...) gives size, not end char* symbol = box_strdup(VersionnedName(name, version, vername)); int ret; - k = kh_put(bridgemap, lib->bridgemap, symbol, &ret); - kh_value(lib->bridgemap, k).name = symbol; - kh_value(lib->bridgemap, k).start = *start; - kh_value(lib->bridgemap, k).end = *end; + k = kh_put(bridgemap, lib->lbridgemap, symbol, &ret); + kh_value(lib->lbridgemap, k).name = symbol; + kh_value(lib->lbridgemap, k).start = *start; + kh_value(lib->lbridgemap, k).end = *end; return 1; } // nope @@ -665,8 +701,14 @@ int GetElfIndex(library_t* lib) return -1; return lib->e.elf_index; } +elfheader_t* GetElf(library_t* lib) +{ + if(!lib || lib->type!=LIB_EMULATED) + return NULL; + return lib->e.elf; +} -static int getSymbolInDataMaps(library_t*lib, const char* name, int noweak, uintptr_t *addr, uintptr_t *size) +static int getSymbolInDataMaps(library_t*lib, const char* name, int noweak, uintptr_t *addr, uintptr_t *size, int* weak) { void* symbol; khint_t k = kh_get(datamap, lib->w.datamap, name); @@ -676,6 +718,7 @@ static int getSymbolInDataMaps(library_t*lib, const char* name, int noweak, uint // found! *addr = (uintptr_t)symbol; *size = kh_value(lib->w.datamap, k); + *weak = 0; return 1; } } @@ -687,6 +730,7 @@ static int getSymbolInDataMaps(library_t*lib, const char* name, int noweak, uint // found! *addr = (uintptr_t)symbol; *size = kh_value(lib->w.wdatamap, k); + *weak = 1; return 1; } } @@ -707,12 +751,13 @@ static int getSymbolInDataMaps(library_t*lib, const char* name, int noweak, uint // found! *addr = (uintptr_t)symbol; *size = kh_value(lib->w.mydatamap, k); + *weak = 0; return 1; } } return 0; } -static int getSymbolInSymbolMaps(library_t*lib, const char* name, int noweak, uintptr_t *addr, uintptr_t *size) +static int getSymbolInSymbolMaps(library_t*lib, const char* name, int noweak, uintptr_t *addr, uintptr_t *size, int* weak) { void* symbol; // check in mysymbolmap @@ -731,6 +776,7 @@ static int getSymbolInSymbolMaps(library_t*lib, const char* name, int noweak, ui AddOffsetSymbol(my_context->maplib, symbol, name); *addr = AddBridge(lib->w.bridge, kh_value(lib->w.mysymbolmap, k), symbol, 0, name); *size = sizeof(void*); + *weak = 0; return 1; } // check in stsymbolmap (return struct...) @@ -749,6 +795,7 @@ static int getSymbolInSymbolMaps(library_t*lib, const char* name, int noweak, ui AddOffsetSymbol(my_context->maplib, symbol, name); *addr = AddBridge(lib->w.bridge, kh_value(lib->w.stsymbolmap, k), symbol, sizeof(void*), name); *size = sizeof(void*); + *weak = 0; return 1; } // check in symbolmap @@ -776,6 +823,7 @@ static int getSymbolInSymbolMaps(library_t*lib, const char* name, int noweak, ui AddOffsetSymbol(my_context->maplib, symbol, name); *addr = AddBridge(lib->w.bridge, kh_value(lib->w.symbolmap, k), symbol, 0, name); *size = sizeof(void*); + *weak = 0; return 1; } if(!noweak) { @@ -795,6 +843,7 @@ static int getSymbolInSymbolMaps(library_t*lib, const char* name, int noweak, ui AddOffsetSymbol(my_context->maplib, symbol, name); *addr = AddBridge(lib->w.bridge, kh_value(lib->w.wmysymbolmap, k), symbol, 0, name); *size = sizeof(void*); + *weak = 1; return 1; } k = kh_get(symbolmap, lib->w.wsymbolmap, name); @@ -821,6 +870,7 @@ static int getSymbolInSymbolMaps(library_t*lib, const char* name, int noweak, ui AddOffsetSymbol(my_context->maplib, symbol, name); *addr = AddBridge(lib->w.bridge, kh_value(lib->w.wsymbolmap, k), symbol, 0, name); *size = sizeof(void*); + *weak = 1; return 1; } } @@ -841,26 +891,27 @@ static int getSymbolInSymbolMaps(library_t*lib, const char* name, int noweak, ui AddOffsetSymbol(my_context->maplib, symbol, name); *addr = AddBridge(lib->w.bridge, kh_value(lib->w.symbol2map, k).w, symbol, 0, name); *size = sizeof(void*); + *weak = kh_value(lib->w.symbol2map, k).weak; return 1; } return 0; } -int getSymbolInMaps(library_t *lib, const char* name, int noweak, uintptr_t *addr, uintptr_t *size, int version, const char* vername, int local) +int getSymbolInMaps(library_t *lib, const char* name, int noweak, uintptr_t *addr, uintptr_t *size, int* weak, int version, const char* vername, int local) { if(!lib->active) return 0; if(version==-2) // don't send global native symbol for a version==-2 search return 0; // check in datamaps (but no version, it's not handled there) - if(getSymbolInDataMaps(lib, name, noweak, addr, size)) + if(getSymbolInDataMaps(lib, name, noweak, addr, size, weak)) return 1; - if(getSymbolInSymbolMaps(lib, VersionnedName(name, version, vername), noweak, addr, size)) + if(getSymbolInSymbolMaps(lib, VersionnedName(name, version, vername), noweak, addr, size, weak)) return 1; - if(getSymbolInSymbolMaps(lib, name, noweak, addr, size)) + if(getSymbolInSymbolMaps(lib, name, noweak, addr, size, weak)) return 1; return 0; @@ -884,7 +935,7 @@ void* GetHandle(library_t* lib) { if(!lib) return NULL; - if(lib->type!=LIB_NATIVE) + if(lib->type!=LIB_WRAPPED) return NULL; return lib->w.lib; } @@ -941,9 +992,66 @@ void AddMainElfToLinkmap(elfheader_t* elf) lm->l_ld = GetDynamicSection(elf); } +static int is_neededlib_present(needed_libs_t* needed, library_t* lib) +{ + if(!needed || !lib) + return 0; + if(!needed->size) + return 0; + for(int i=0; i<needed->size; ++i) + if(needed->libs[i] == lib) + return 1; + return 0; +} + +void add_neededlib(needed_libs_t* needed, library_t* lib) +{ + if(!needed) + return; + if(is_neededlib_present(needed, lib)) + return; + if(needed->size == needed->cap) { + needed->cap += 8; + needed->libs = (library_t**)realloc(needed->libs, needed->cap*sizeof(library_t*)); + } + needed->libs[needed->size++] = lib; +} +void free_neededlib(needed_libs_t* needed) +{ + if(!needed) + return; + needed->cap = 0; + needed->size = 0; + if(needed->libs) + free(needed->libs); + needed->libs = NULL; +} +void add_dependedbylib(needed_libs_t* dependedby, library_t* lib) +{ + if(!dependedby) + return; + if(is_neededlib_present(dependedby, lib)) + return; + if(dependedby->size == dependedby->cap) { + dependedby->cap += 8; + dependedby->libs = (library_t**)realloc(dependedby->libs, dependedby->cap*sizeof(library_t*)); + } + dependedby->libs[dependedby->size++] = lib; +} +void free_dependedbylib(needed_libs_t* dependedby) +{ + if(!dependedby) + return; + dependedby->cap = 0; + dependedby->size = 0; + if(dependedby->libs) + free(dependedby->libs); + dependedby->libs = NULL; +} + void setNeededLibs(library_t* lib, int n, ...) { - if(lib->type!=LIB_NATIVE && lib->type!=LIB_UNNKNOW) + if(lib->type!=LIB_WRAPPED && lib->type!=LIB_UNNKNOW) return; lib->w.needed = n; lib->w.neededlibs = (char**)box_calloc(n, sizeof(char*)); @@ -953,4 +1061,4 @@ void setNeededLibs(library_t* lib, int n, ...) lib->w.neededlibs[i] = box_strdup(va_arg(va, char*)); } va_end (va); -} \ No newline at end of file +} |