about summary refs log tree commit diff stats
path: root/src/librarian/library.c
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2022-10-22 20:57:31 +0200
committerptitSeb <sebastien.chev@gmail.com>2022-10-22 20:57:31 +0200
commit58cdb1bda2f2dd6a0bc5ea42e99b279fc687c06b (patch)
tree099bf5dc7d814272d6842df6656c2e672d5a1143 /src/librarian/library.c
parenta530f565110875c431ff9600ee9da4a640599ec7 (diff)
downloadbox64-58cdb1bda2f2dd6a0bc5ea42e99b279fc687c06b.tar.gz
box64-58cdb1bda2f2dd6a0bc5ea42e99b279fc687c06b.zip
Refactored, again, elfloader symbol fetching (ported from box86)
Diffstat (limited to 'src/librarian/library.c')
-rwxr-xr-xsrc/librarian/library.c280
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
+}