diff --git a/tcc.c b/tcc.c index 652b918..b402a9b 100644 --- a/tcc.c +++ b/tcc.c @@ -222,6 +222,7 @@ typedef struct Section { typedef struct DLLReference { int level; + void *handle; char name[1]; } DLLReference; @@ -9486,8 +9487,6 @@ static void preprocess_init(TCCState *s1) vtop = vstack - 1; s1->pack_stack[0] = 0; s1->pack_stack_ptr = s1->pack_stack; - - macro_ptr = NULL; } /* compile the C file opened in 'file'. Return non zero if errors. */ @@ -10095,6 +10094,8 @@ static void tcc_cleanup(void) cstr_free(&tokcstr); /* reset symbol stack */ sym_free_first = NULL; + /* cleanup from error/setjmp */ + macro_ptr = NULL; } TCCState *tcc_new(void) @@ -10227,6 +10228,14 @@ void tcc_delete(TCCState *s1) for(i = 1; i < s1->nb_sections; i++) free_section(s1->sections[i]); tcc_free(s1->sections); + + /* free any loaded DLLs */ + for ( i = 0; i < s1->nb_loaded_dlls; i++) + { + DLLReference *ref = s1->loaded_dlls[i]; + if ( ref->handle ) + dlclose(ref->handle); + } /* free loaded dlls array */ dynarray_reset(&s1->loaded_dlls, &s1->nb_loaded_dlls); diff --git a/tccelf.c b/tccelf.c index 62f8c33..7de8a48 100644 --- a/tccelf.c +++ b/tccelf.c @@ -2276,7 +2276,7 @@ static int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level) // printf("loading dll '%s'\n", soname); /* add the dll and its level */ - dllref = tcc_malloc(sizeof(DLLReference) + strlen(soname)); + dllref = tcc_mallocz(sizeof(DLLReference) + strlen(soname)); dllref->level = level; strcpy(dllref->name, soname); dynarray_add((void ***)&s1->loaded_dlls, &s1->nb_loaded_dlls, dllref); diff --git a/tccpe.c b/tccpe.c index 25b5413..6b68ff0 100644 --- a/tccpe.c +++ b/tccpe.c @@ -465,6 +465,8 @@ ST_FN int pe_find_import(TCCState * s1, const char *symbol) # include # define LoadLibrary(s) dlopen(s, RTLD_NOW) # define GetProcAddress(h,s) dlsym(h, s) +#else +# define dlclose(h) FreeLibrary(h) #endif /* for the -run option: dynamically load symbol from dll */ @@ -472,16 +474,21 @@ void *resolve_sym(struct TCCState *s1, const char *symbol, int type) { char buffer[100]; int sym_index, dll_index; - void *hModule, *addr, **m; + void *addr, **m; + DLLReference *dllref; sym_index = pe_find_import(s1, symbol); if (0 == sym_index) return NULL; dll_index = ((Elf32_Sym *)s1->dynsymtab_section->data + sym_index)->st_value; - hModule = LoadLibrary(s1->loaded_dlls[dll_index-1]->name); - addr = GetProcAddress(hModule, symbol); + dllref = s1->loaded_dlls[dll_index-1]; + if ( !dllref->handle ) + { + dllref->handle = LoadLibrary(dllref->name); + } + addr = GetProcAddress(dllref->handle, symbol); if (NULL == addr) - addr = GetProcAddress(hModule, get_alt_symbol(buffer, symbol)); + addr = GetProcAddress(dllref->handle, get_alt_symbol(buffer, symbol)); if (addr && STT_OBJECT == type) { /* need to return a pointer to the address for data objects */ @@ -1413,9 +1420,8 @@ PUB_FN int pe_load_def_file(TCCState *s1, int fd) continue; case 2: - dllref = tcc_malloc(sizeof(DLLReference) + strlen(dllname)); + dllref = tcc_mallocz(sizeof(DLLReference) + strlen(dllname)); strcpy(dllref->name, dllname); - dllref->level = 0; dynarray_add((void ***) &s1->loaded_dlls, &s1->nb_loaded_dlls, dllref); ++state;