about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--src/wrapped/wrappedlibdl.c135
1 files changed, 48 insertions, 87 deletions
diff --git a/src/wrapped/wrappedlibdl.c b/src/wrapped/wrappedlibdl.c
index dd40a1aa..f91e379e 100644
--- a/src/wrapped/wrappedlibdl.c
+++ b/src/wrapped/wrappedlibdl.c
@@ -27,12 +27,14 @@ typedef struct dllib_s {
     int         full;
 } dllib_t;
 
+#define ERROR_LEN 128
 typedef struct dlprivate_s {
     dllib_t     *dllibs;
     size_t      lib_sz;
     size_t      lib_cap;
-    char*       last_error;
-    char        error_msg[100];
+    char        error_msg[ERROR_LEN];
+    char        last_msg[ERROR_LEN];
+    int         is_error;
 } dlprivate_t;
 
 dlprivate_t *NewDLPrivate() {
@@ -40,7 +42,6 @@ dlprivate_t *NewDLPrivate() {
     return dl;
 }
 void FreeDLPrivate(dlprivate_t **lib) {
-    box_free((*lib)->last_error);
     box_free(*lib);
 }
 
@@ -62,7 +63,7 @@ int my_dlinfo(x64emu_t* emu, void* handle, int request, void* info) EXPORT;
 const char* libdlName = "libdl.so.2";
 #define ALTNAME "libdl.so"
 
-#define CLEARERR    if(dl->last_error) {box_free(dl->last_error); dl->last_error = NULL;}
+#define CLEARERR    dl->is_error = 0
 void dl_clear_error()
 {
     dlprivate_t *dl = my_context->dlprivate;
@@ -72,39 +73,36 @@ void dl_clear_error()
 void dl_set_error(const char* msg)
 {
     dlprivate_t *dl = my_context->dlprivate;
-    if(!dl->last_error)
-        dl->last_error = box_calloc(1, 129);
-    snprintf(dl->last_error, 129, "%s", msg);
+    snprintf(dl->last_msg, ERROR_LEN, "%s", msg);
+    dl->is_error = 1;
 }
 
+#define SET_ERROR(M, ...) do { snprintf(dl->last_msg, ERROR_LEN, M, __VA_ARGS__); dl->is_error=1; } while(0)
+
 library_t* dl_get_library(void* handle)
 {
     dlprivate_t *dl = my_context->dlprivate;
-    CLEARERR
+    CLEARERR;
     size_t nlib = (size_t)handle;
     --nlib;
     // size_t is unsigned
     if(nlib>=dl->lib_sz) {
-        if(!dl->last_error)
-            dl->last_error = box_calloc(1, 129);
-        snprintf(dl->last_error, 129, "Bad handle %p)\n", handle);
+        SET_ERROR("Bad handle %p)\n", handle);
         return (void*)-1LL;
     }
     if(!dl->dllibs[nlib].count || !dl->dllibs[nlib].full) {
-        if(!dl->last_error)
-            dl->last_error = box_calloc(1, 129);
-        snprintf(dl->last_error, 129, "Bad handle %p (already closed))\n", handle);
+        SET_ERROR("Bad handle %p (already closed))\n", handle);
         return (void*)-1LL;
     }
     return dl->dllibs[nlib].lib;
 }
-
+#ifdef BOX32
 char* dl_last_error()
 {
     dlprivate_t *dl = my_context->dlprivate;
-    return dl->last_error;
+    return dl->last_msg;
 }
-
+#endif
 void RemoveDlopen(library_t** lib, size_t idx)
 {
     if(!my_context)
@@ -132,7 +130,7 @@ void* my_dlopen(x64emu_t* emu, void *filename, int flag)
     size_t dlopened = 0;
     int is_local = (flag&0x100)?0:1;  // if not global, then local, and that means symbols are not put in the global "pot" for other libs
     int deepbind = (flag&0x0008)?1:0;  // RTLD_DEEPBIND means LOCAL before GLOBAL scope during symbol resolution
-    CLEARERR
+    CLEARERR;
     if(filename) {
         char* rfilename = (char*)alloca(MAX_PATH);
         strcpy(rfilename, (char*)filename);
@@ -233,9 +231,7 @@ void* my_dlopen(x64emu_t* emu, void *filename, int flag)
         tmp->names[0] = rfilename;
         if(AddNeededLib(NULL, is_local, bindnow, deepbind, tmp, NULL, my_context, emu)) {
             printf_dlsym(strchr(rfilename,'/')?LOG_DEBUG:LOG_INFO, "Warning: Cannot dlopen(\"%s\"/%p, %X)\n", rfilename, filename, flag);
-            if(!dl->last_error)
-                dl->last_error = box_calloc(1, 129);
-            snprintf(dl->last_error, 129, "Cannot dlopen(\"%s\"/%p, %X)\n", rfilename, filename, flag);
+            SET_ERROR("Cannot dlopen(\"%s\"/%p, %X)\n", rfilename, filename, flag);
             RemoveNeededLib(NULL, is_local, tmp, my_context, emu);
             if(my_context->deferredInitList)
                 box_free(my_context->deferredInitList);
@@ -295,11 +291,10 @@ char* my_dlerror(x64emu_t* emu)
 {
     dlprivate_t *dl = my_context->dlprivate;
     //printf_dlsym(LOG_INFO, "call to dlerror(): \"%s\"\n", dl->last_error?dl->last_error:"(nil)"); //too chatty
-    if(!dl->last_error)
+    if(!dl->is_error)
         return NULL;
-    strncpy(dl->error_msg, dl->last_error, sizeof(dl->error_msg)-1);
-    box_free(dl->last_error);
-    dl->last_error = NULL;
+    strncpy(dl->error_msg, dl->last_msg, ERROR_LEN);
+    dl->is_error = 0;
     return dl->error_msg;
 }
 
@@ -353,7 +348,7 @@ void* my_dlsym(x64emu_t* emu, void *handle, void *symbol)
     char* rsymbol = (char*)symbol;
     if(box64_is32bits && handle==(void*)0xffffffff)
         handle = (void*)~0LL;
-    CLEARERR
+    CLEARERR;
     printf_dlsym(LOG_DEBUG, "%04d|Call to dlsym(%p, \"%s\")%s", GetTID(), handle, rsymbol, BOX64ENV(dlsym_error)?"":"\n");
     if(handle==NULL) {
         // special case, look globably
@@ -362,9 +357,7 @@ void* my_dlsym(x64emu_t* emu, void *handle, void *symbol)
             pthread_mutex_unlock(&mutex);
             return (void*)start;
         }
-        if(!dl->last_error)
-            dl->last_error = box_calloc(1, 129);
-        snprintf(dl->last_error, 129, "Symbol \"%s\" not found in %p)\n", rsymbol, handle);
+        SET_ERROR("Symbol \"%s\" not found in %p)\n", rsymbol, handle);
         printf_dlsym_prefix(0, LOG_NEVER, "%p\n", NULL);
         pthread_mutex_unlock(&mutex);
         return NULL;
@@ -384,9 +377,7 @@ void* my_dlsym(x64emu_t* emu, void *handle, void *symbol)
             pthread_mutex_unlock(&mutex);
             return (void*)start;
         }
-        if(!dl->last_error)
-            dl->last_error = box_calloc(1, 129);
-        snprintf(dl->last_error, 129, "Symbol \"%s\" not found in %p)\n", rsymbol, handle);
+        SET_ERROR("Symbol \"%s\" not found in %p)\n", rsymbol, handle);
         printf_dlsym(LOG_NEVER, "%p\n", NULL);
         pthread_mutex_unlock(&mutex);
         return NULL;
@@ -395,17 +386,13 @@ void* my_dlsym(x64emu_t* emu, void *handle, void *symbol)
     --nlib;
     // size_t is unsigned
     if(nlib>=dl->lib_sz) {
-        if(!dl->last_error)
-            dl->last_error = box_calloc(1, 129);
-        snprintf(dl->last_error, 129, "Bad handle %p)\n", handle);
+        SET_ERROR("Bad handle %p)\n", handle);
         printf_dlsym(LOG_NEVER, "%p\n", NULL);
         pthread_mutex_unlock(&mutex);
         return NULL;
     }
     if(!dl->dllibs[nlib].count || !dl->dllibs[nlib].full) {
-        if(!dl->last_error)
-            dl->last_error = box_calloc(1, 129);
-        snprintf(dl->last_error, 129, "Bad handle %p (already closed))\n", handle);
+        SET_ERROR("Bad handle %p (already closed))\n", handle);
         printf_dlsym(LOG_NEVER, "%p\n", (void*)NULL);
         pthread_mutex_unlock(&mutex);
         return NULL;
@@ -415,9 +402,7 @@ void* my_dlsym(x64emu_t* emu, void *handle, void *symbol)
             // not found
             printf_dlsym(LOG_NEVER, "%p\nCall to dlsym(%s, \"%s\") Symbol not found\n", NULL, GetNameLib(dl->dllibs[nlib].lib), rsymbol);
             printf_log(LOG_DEBUG, " Symbol not found\n");
-            if(!dl->last_error)
-                dl->last_error = box_calloc(1, 129);
-            snprintf(dl->last_error, 129, "Symbol \"%s\" not found in %p(%s)", rsymbol, handle, GetNameLib(dl->dllibs[nlib].lib));
+            SET_ERROR("Symbol \"%s\" not found in %p(%s)", rsymbol, handle, GetNameLib(dl->dllibs[nlib].lib));
             pthread_mutex_unlock(&mutex);
             return NULL;
         }
@@ -437,9 +422,7 @@ void* my_dlsym(x64emu_t* emu, void *handle, void *symbol)
             pthread_mutex_unlock(&mutex);
             return (void*)start;
         }
-        if(!dl->last_error)
-            dl->last_error = box_calloc(1, 129);
-        snprintf(dl->last_error, 129, "Symbol \"%s\" not found in %p)\n", rsymbol, handle);
+        SET_ERROR("Symbol \"%s\" not found in %p)\n", rsymbol, handle);
         printf_dlsym(LOG_NEVER, "%p\n", NULL);
         pthread_mutex_unlock(&mutex);
         return NULL;
@@ -454,22 +437,18 @@ int my_dlclose(x64emu_t* emu, void *handle)
     (void)emu;
     printf_dlsym(LOG_DEBUG, "Call to dlclose(%p)\n", handle);
     dlprivate_t *dl = my_context->dlprivate;
-    CLEARERR
+    CLEARERR;
     size_t nlib = (size_t)handle;
     --nlib;
     // size_t is unsigned
     if(nlib>=dl->lib_sz) {
-        if(!dl->last_error)
-            dl->last_error = box_calloc(1, 129);
-        snprintf(dl->last_error, 129, "Bad handle %p)\n", handle);
-        printf_dlsym(LOG_DEBUG, "dlclose: %s\n", dl->last_error);
+        SET_ERROR("Bad handle %p)\n", handle);
+        printf_dlsym(LOG_DEBUG, "dlclose: %s\n", dl->last_msg);
         return -1;
     }
     if(!dl->dllibs[nlib].count || !dl->dllibs[nlib].full) {
-        if(!dl->last_error)
-            dl->last_error = box_calloc(1, 129);
-        snprintf(dl->last_error, 129, "Bad handle %p (already closed))\n", handle);
-        printf_dlsym(LOG_DEBUG, "dlclose: %s\n", dl->last_error);
+        SET_ERROR("Bad handle %p (already closed))\n", handle);
+        printf_dlsym(LOG_DEBUG, "dlclose: %s\n", dl->last_msg);
         return -1;
     }
     --dl->dllibs[nlib].count;
@@ -491,7 +470,7 @@ int my_dladdr1(x64emu_t* emu, void *addr, void *i, void** extra_info, int flags)
 {
     //int dladdr(void *addr, Dl_info *info);
     dlprivate_t *dl = my_context->dlprivate;
-    CLEARERR
+    CLEARERR;
     Dl_info *info = (Dl_info*)i;
     printf_log(LOG_DEBUG, "Warning: partially unimplement call to dladdr/dladdr1(%p, %p, %p, %d)\n", addr, info, extra_info, flags);
     
@@ -521,7 +500,7 @@ void* my_dlvsym(x64emu_t* emu, void *handle, void *symbol, const char *vername)
     char* rsymbol = (char*)symbol;
     if(box64_is32bits && handle==(void*)0xffffffff)
         handle = (void*)~0LL;
-    CLEARERR
+    CLEARERR;
     printf_dlsym(LOG_DEBUG, "Call to dlvsym(%p, \"%s\", %s)%s", handle, rsymbol, vername?vername:"(nil)", BOX64ENV(dlsym_error)?"":"\n");
     if(handle==NULL) {
         // special case, look globably
@@ -529,9 +508,7 @@ void* my_dlvsym(x64emu_t* emu, void *handle, void *symbol, const char *vername)
             printf_dlsym_prefix(0, LOG_NEVER, "%p\n", (void*)start);
             return (void*)start;
         }
-        if(!dl->last_error)
-            dl->last_error = box_calloc(1, 129);
-        snprintf(dl->last_error, 129, "Symbol \"%s\" version %s not found in %p)\n", rsymbol, vername?vername:"(nil)", handle);
+        SET_ERROR("Symbol \"%s\" version %s not found in %p)\n", rsymbol, vername?vername:"(nil)", handle);
         printf_dlsym_prefix(0, LOG_NEVER, "%p\n", NULL);
         return NULL;
     }
@@ -549,9 +526,7 @@ void* my_dlvsym(x64emu_t* emu, void *handle, void *symbol, const char *vername)
                 printf_dlsym(LOG_NEVER, "%p\n", (void*)start);
             return (void*)start;
         }
-        if(!dl->last_error)
-            dl->last_error = box_calloc(1, 129);
-        snprintf(dl->last_error, 129, "Symbol \"%s\" version %s not found in %p)\n", rsymbol, vername?vername:"(nil)", handle);
+        SET_ERROR("Symbol \"%s\" version %s not found in %p)\n", rsymbol, vername?vername:"(nil)", handle);
             printf_dlsym(LOG_NEVER, "%p\n", NULL);
         return NULL;
     }
@@ -559,17 +534,13 @@ void* my_dlvsym(x64emu_t* emu, void *handle, void *symbol, const char *vername)
     --nlib;
     // size_t is unsigned
     if(nlib>=dl->lib_sz) {
-        if(!dl->last_error)
-            dl->last_error = box_calloc(1, 129);
-        snprintf(dl->last_error, 129, "Bad handle %p)\n", handle);
-            printf_dlsym(LOG_NEVER, "%p\n", NULL);
+        SET_ERROR("Bad handle %p)\n", handle);
+        printf_dlsym(LOG_NEVER, "%p\n", NULL);
         return NULL;
     }
     if(!dl->dllibs[nlib].count || !dl->dllibs[nlib].full) {
-        if(!dl->last_error)
-            dl->last_error = box_calloc(1, 129);
-        snprintf(dl->last_error, 129, "Bad handle %p (already closed))\n", handle);
-            printf_dlsym(LOG_NEVER, "%p\n", (void*)NULL);
+        SET_ERROR("Bad handle %p (already closed))\n", handle);
+        printf_dlsym(LOG_NEVER, "%p\n", (void*)NULL);
         return NULL;
     }
     if(dl->dllibs[nlib].lib) {
@@ -577,9 +548,7 @@ void* my_dlvsym(x64emu_t* emu, void *handle, void *symbol, const char *vername)
             // not found
                 printf_dlsym(LOG_NEVER, "%p\nCall to dlvsym(%s, \"%s\", %s) Symbol not found\n", NULL, GetNameLib(dl->dllibs[nlib].lib), rsymbol, vername?vername:"(nil)");
             printf_log(LOG_DEBUG, " Symbol not found\n");
-            if(!dl->last_error)
-                dl->last_error = box_calloc(1, 129);
-            snprintf(dl->last_error, 129, "Symbol \"%s\" not found in %p(%s)", rsymbol, handle, GetNameLib(dl->dllibs[nlib].lib));
+            SET_ERROR("Symbol \"%s\" not found in %p(%s)", rsymbol, handle, GetNameLib(dl->dllibs[nlib].lib));
             return NULL;
         }
     } else {
@@ -591,9 +560,7 @@ void* my_dlvsym(x64emu_t* emu, void *handle, void *symbol, const char *vername)
         // not found
             printf_dlsym(LOG_NEVER, "%p\nCall to dlvsym(%s, \"%s\", %s) Symbol not found\n", NULL, "Self", rsymbol, vername?vername:"(nil)");
         printf_log(LOG_DEBUG, " Symbol not found\n");
-        if(!dl->last_error)
-            dl->last_error = box_calloc(1, 129);
-        snprintf(dl->last_error, 129, "Symbol \"%s\" version %s not found in %p)\n", rsymbol, vername?vername:"(nil)", handle);
+        SET_ERROR("Symbol \"%s\" version %s not found in %p)\n", rsymbol, vername?vername:"(nil)", handle);
         return NULL;
     }
         printf_dlsym(LOG_NEVER, "%p\n", (void*)start);
@@ -605,22 +572,18 @@ int my_dlinfo(x64emu_t* emu, void* handle, int request, void* info)
     (void)emu;
     printf_dlsym(LOG_DEBUG, "Call to dlinfo(%p, %d, %p)\n", handle, request, info);
     dlprivate_t *dl = my_context->dlprivate;
-    CLEARERR
+    CLEARERR;
     size_t nlib = (size_t)handle;
     --nlib;
     // size_t is unsigned
     if(nlib>=dl->lib_sz) {
-        if(!dl->last_error)
-            dl->last_error = box_calloc(1, 129);
-        snprintf(dl->last_error, 129, "Bad handle %p)\n", handle);
-        printf_dlsym(LOG_DEBUG, "dlinfo: %s\n", dl->last_error);
+        SET_ERROR("Bad handle %p)\n", handle);
+        printf_dlsym(LOG_DEBUG, "dlinfo: %s\n", dl->last_msg);
         return -1;
     }
     if(!dl->dllibs[nlib].count || !dl->dllibs[nlib].full) {
-        if(!dl->last_error)
-            dl->last_error = box_calloc(1, 129);
-        snprintf(dl->last_error, 129, "Bad handle %p (already closed))\n", handle);
-        printf_dlsym(LOG_DEBUG, "dlinfo: %s\n", dl->last_error);
+        SET_ERROR("Bad handle %p (already closed))\n", handle);
+        printf_dlsym(LOG_DEBUG, "dlinfo: %s\n", dl->last_msg);
         return -1;
     }
     library_t *lib = dl->dllibs[nlib].lib;
@@ -633,9 +596,7 @@ int my_dlinfo(x64emu_t* emu, void* handle, int request, void* info)
             return 0;
         default:
             printf_log(LOG_NONE, "Warning, unsupported call to dlinfo(%p, %d, %p)\n", handle, request, info);
-        if(!dl->last_error)
-            dl->last_error = box_calloc(1, 129);
-        snprintf(dl->last_error, 129, "unsupported call to dlinfo request:%d\n", request);
+            SET_ERROR("unsupported call to dlinfo request:%d\n", request);
     }
     return -1;
 }