aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgrischka <grischka>2008-05-05 22:40:49 +0000
committergrischka <grischka>2008-05-05 22:40:49 +0000
commitf9bf48d6433a0e9a317fe8beba9c8daf429ff6ed (patch)
treef30d2533e8d39eaf27d0ee44a8d447fa81f5fda2
parent96bd8f2b25f12e4859f8666fc0b33063d47dd730 (diff)
downloadtinycc-f9bf48d6433a0e9a317fe8beba9c8daf429ff6ed.tar.gz
tinycc-f9bf48d6433a0e9a317fe8beba9c8daf429ff6ed.tar.bz2
release loaded dlls cleanly (Sam K)
-rw-r--r--tcc.c13
-rw-r--r--tccelf.c2
-rw-r--r--tccpe.c18
3 files changed, 24 insertions, 9 deletions
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 <dlfcn.h>
# 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;