mirror of
https://github.com/mirror/tinycc.git
synced 2025-01-03 04:30:08 +08:00
release loaded dlls cleanly (Sam K)
This commit is contained in:
parent
96bd8f2b25
commit
f9bf48d643
13
tcc.c
13
tcc.c
@ -222,6 +222,7 @@ typedef struct Section {
|
|||||||
|
|
||||||
typedef struct DLLReference {
|
typedef struct DLLReference {
|
||||||
int level;
|
int level;
|
||||||
|
void *handle;
|
||||||
char name[1];
|
char name[1];
|
||||||
} DLLReference;
|
} DLLReference;
|
||||||
|
|
||||||
@ -9486,8 +9487,6 @@ static void preprocess_init(TCCState *s1)
|
|||||||
vtop = vstack - 1;
|
vtop = vstack - 1;
|
||||||
s1->pack_stack[0] = 0;
|
s1->pack_stack[0] = 0;
|
||||||
s1->pack_stack_ptr = s1->pack_stack;
|
s1->pack_stack_ptr = s1->pack_stack;
|
||||||
|
|
||||||
macro_ptr = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* compile the C file opened in 'file'. Return non zero if errors. */
|
/* compile the C file opened in 'file'. Return non zero if errors. */
|
||||||
@ -10095,6 +10094,8 @@ static void tcc_cleanup(void)
|
|||||||
cstr_free(&tokcstr);
|
cstr_free(&tokcstr);
|
||||||
/* reset symbol stack */
|
/* reset symbol stack */
|
||||||
sym_free_first = NULL;
|
sym_free_first = NULL;
|
||||||
|
/* cleanup from error/setjmp */
|
||||||
|
macro_ptr = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
TCCState *tcc_new(void)
|
TCCState *tcc_new(void)
|
||||||
@ -10228,6 +10229,14 @@ void tcc_delete(TCCState *s1)
|
|||||||
free_section(s1->sections[i]);
|
free_section(s1->sections[i]);
|
||||||
tcc_free(s1->sections);
|
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 */
|
/* free loaded dlls array */
|
||||||
dynarray_reset(&s1->loaded_dlls, &s1->nb_loaded_dlls);
|
dynarray_reset(&s1->loaded_dlls, &s1->nb_loaded_dlls);
|
||||||
|
|
||||||
|
2
tccelf.c
2
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);
|
// printf("loading dll '%s'\n", soname);
|
||||||
|
|
||||||
/* add the dll and its level */
|
/* add the dll and its level */
|
||||||
dllref = tcc_malloc(sizeof(DLLReference) + strlen(soname));
|
dllref = tcc_mallocz(sizeof(DLLReference) + strlen(soname));
|
||||||
dllref->level = level;
|
dllref->level = level;
|
||||||
strcpy(dllref->name, soname);
|
strcpy(dllref->name, soname);
|
||||||
dynarray_add((void ***)&s1->loaded_dlls, &s1->nb_loaded_dlls, dllref);
|
dynarray_add((void ***)&s1->loaded_dlls, &s1->nb_loaded_dlls, dllref);
|
||||||
|
18
tccpe.c
18
tccpe.c
@ -465,6 +465,8 @@ ST_FN int pe_find_import(TCCState * s1, const char *symbol)
|
|||||||
# include <dlfcn.h>
|
# include <dlfcn.h>
|
||||||
# define LoadLibrary(s) dlopen(s, RTLD_NOW)
|
# define LoadLibrary(s) dlopen(s, RTLD_NOW)
|
||||||
# define GetProcAddress(h,s) dlsym(h, s)
|
# define GetProcAddress(h,s) dlsym(h, s)
|
||||||
|
#else
|
||||||
|
# define dlclose(h) FreeLibrary(h)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* for the -run option: dynamically load symbol from dll */
|
/* 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];
|
char buffer[100];
|
||||||
int sym_index, dll_index;
|
int sym_index, dll_index;
|
||||||
void *hModule, *addr, **m;
|
void *addr, **m;
|
||||||
|
DLLReference *dllref;
|
||||||
|
|
||||||
sym_index = pe_find_import(s1, symbol);
|
sym_index = pe_find_import(s1, symbol);
|
||||||
if (0 == sym_index)
|
if (0 == sym_index)
|
||||||
return NULL;
|
return NULL;
|
||||||
dll_index = ((Elf32_Sym *)s1->dynsymtab_section->data + sym_index)->st_value;
|
dll_index = ((Elf32_Sym *)s1->dynsymtab_section->data + sym_index)->st_value;
|
||||||
hModule = LoadLibrary(s1->loaded_dlls[dll_index-1]->name);
|
dllref = s1->loaded_dlls[dll_index-1];
|
||||||
addr = GetProcAddress(hModule, symbol);
|
if ( !dllref->handle )
|
||||||
|
{
|
||||||
|
dllref->handle = LoadLibrary(dllref->name);
|
||||||
|
}
|
||||||
|
addr = GetProcAddress(dllref->handle, symbol);
|
||||||
if (NULL == addr)
|
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) {
|
if (addr && STT_OBJECT == type) {
|
||||||
/* need to return a pointer to the address for data objects */
|
/* 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;
|
continue;
|
||||||
|
|
||||||
case 2:
|
case 2:
|
||||||
dllref = tcc_malloc(sizeof(DLLReference) + strlen(dllname));
|
dllref = tcc_mallocz(sizeof(DLLReference) + strlen(dllname));
|
||||||
strcpy(dllref->name, dllname);
|
strcpy(dllref->name, dllname);
|
||||||
dllref->level = 0;
|
|
||||||
dynarray_add((void ***) &s1->loaded_dlls, &s1->nb_loaded_dlls, dllref);
|
dynarray_add((void ***) &s1->loaded_dlls, &s1->nb_loaded_dlls, dllref);
|
||||||
++state;
|
++state;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user