From 52a9a541b0aeedf9b6f3b9cf551815e2c335f160 Mon Sep 17 00:00:00 2001 From: waterlens Date: Tue, 18 Mar 2025 23:54:08 +0800 Subject: [PATCH] Fix `tcc -run` on Windows --- libtcc.c | 18 +++++++++++++----- tcc.h | 4 ++-- tccelf.c | 17 +++++++++++++---- tccmacho.c | 2 +- tccpe.c | 8 +++++--- 5 files changed, 34 insertions(+), 15 deletions(-) diff --git a/libtcc.c b/libtcc.c index b163e865..bce9dd3c 100644 --- a/libtcc.c +++ b/libtcc.c @@ -78,6 +78,10 @@ ST_DATA int nb_stk_data; /* option -d (for general development purposes) */ ST_DATA int g_debug; +#define DEBUG_LIBTCC 0 +#undef dprintf +#define dprintf if (DEBUG_LIBTCC) printf + /********************************************************/ #ifdef _WIN32 ST_FUNC char *normalize_slashes(char *path) @@ -963,15 +967,19 @@ LIBTCCAPI int tcc_add_sysinclude_path(TCCState *s, const char *pathname) } /* add/update a 'DLLReference', Just find if level == -1 */ -ST_FUNC DLLReference *tcc_add_dllref(TCCState *s1, const char *dllname, int level) +ST_FUNC DLLReference *tcc_add_dllref(TCCState *s1, const char *dllpath, int level) { DLLReference *ref = NULL; int i; - for (i = 0; i < s1->nb_loaded_dlls; i++) - if (0 == strcmp(s1->loaded_dlls[i]->name, dllname)) { + const char *dllname = tcc_basename(dllpath); + const char *name; + for (i = 0; i < s1->nb_loaded_dlls; i++) { + name = tcc_basename(s1->loaded_dlls[i]->path); + if (0 == strcmp(name, dllname)) { ref = s1->loaded_dlls[i]; break; } + } if (level == -1) return ref; if (ref) { @@ -980,8 +988,8 @@ ST_FUNC DLLReference *tcc_add_dllref(TCCState *s1, const char *dllname, int leve ref->found = 1; return ref; } - ref = tcc_mallocz(sizeof(DLLReference) + strlen(dllname)); - strcpy(ref->name, dllname); + ref = tcc_mallocz(sizeof(DLLReference) + strlen(dllpath)); + strcpy(ref->path, dllpath); dynarray_add(&s1->loaded_dlls, &s1->nb_loaded_dlls, ref); ref->level = level; ref->index = s1->nb_loaded_dlls; diff --git a/tcc.h b/tcc.h index 45e7b5b7..687fb607 100644 --- a/tcc.h +++ b/tcc.h @@ -583,7 +583,7 @@ typedef struct DLLReference { int level; void *handle; unsigned char found, index; - char name[1]; + char path[1]; } DLLReference; /* -------------------------------------------------- */ @@ -1293,7 +1293,7 @@ PUB_FUNC int tcc_parse_args(TCCState *s, int *argc, char ***argv, int optind); #ifdef _WIN32 ST_FUNC char *normalize_slashes(char *path); #endif -ST_FUNC DLLReference *tcc_add_dllref(TCCState *s1, const char *dllname, int level); +ST_FUNC DLLReference *tcc_add_dllref(TCCState *s1, const char *dllpath, int level); ST_FUNC char *tcc_load_text(int fd); /* for #pragma once */ ST_FUNC int normalized_PATHCMP(const char *f1, const char *f2); diff --git a/tccelf.c b/tccelf.c index ee3e6360..8e11c1bf 100644 --- a/tccelf.c +++ b/tccelf.c @@ -1056,9 +1056,17 @@ ST_FUNC void relocate_syms(TCCState *s1, Section *symtab, int do_resolve) name = (char *) s1->symtab->link->data + sym->st_name; /* Use ld.so to resolve symbol for us (for tcc -run) */ if (do_resolve) { -#if defined TCC_IS_NATIVE && !defined TCC_TARGET_PE + void *addr = NULL; +#if defined(TCC_IS_NATIVE) +#if defined(TCC_TARGET_PE) + int i; + for (i = 0; i < s1->nb_loaded_dlls; i++) { + if ((addr = GetProcAddress(s1->loaded_dlls[i]->handle, name))) + break; + } +#else /* dlsym() needs the undecorated name. */ - void *addr = dlsym(RTLD_DEFAULT, &name[s1->leading_underscore]); + addr = dlsym(RTLD_DEFAULT, &name[s1->leading_underscore]); #if TARGETOS_OpenBSD || TARGETOS_FreeBSD || TARGETOS_NetBSD || TARGETOS_ANDROID if (addr == NULL) { int i; @@ -1066,6 +1074,7 @@ ST_FUNC void relocate_syms(TCCState *s1, Section *symtab, int do_resolve) if ((addr = dlsym(s1->loaded_dlls[i]->handle, name))) break; } +#endif #endif if (addr) { sym->st_value = (addr_t) addr; @@ -2901,7 +2910,7 @@ static int elf_output_file(TCCState *s1, const char *filename) for(i = 0; i < s1->nb_loaded_dlls; i++) { DLLReference *dllref = s1->loaded_dlls[i]; if (dllref->level == 0) - put_dt(dynamic, DT_NEEDED, put_elf_str(dynstr, dllref->name)); + put_dt(dynamic, DT_NEEDED, put_elf_str(dynstr, tcc_basename(dllref->path))); } if (s1->rpath) @@ -3723,7 +3732,7 @@ ST_FUNC int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level) soname = dynstr + dt->d_un.d_val; /* if the dll is already loaded, do not load it */ - if (tcc_add_dllref(s1, soname, level)->found) + if (tcc_add_dllref(s1, filename, level)->found) goto ret_success; if (v.nb_versyms != nb_syms) diff --git a/tccmacho.c b/tccmacho.c index 0b70457c..47a8f2fe 100644 --- a/tccmacho.c +++ b/tccmacho.c @@ -1770,7 +1770,7 @@ static void collect_sections(TCCState *s1, struct macho *mo, const char *filenam for(i = 0; i < s1->nb_loaded_dlls; i++) { DLLReference *dllref = s1->loaded_dlls[i]; if (dllref->level == 0) - add_dylib(mo, dllref->name); + add_dylib(mo, tcc_basename(dllref->path)); } if (s1->rpath) { diff --git a/tccpe.c b/tccpe.c index 1ec3e762..07a27c88 100644 --- a/tccpe.c +++ b/tccpe.c @@ -848,7 +848,9 @@ static void pe_build_imports(struct pe_info *pe) dllindex = p->dll_index; if (dllindex) - name = (dllref = pe->s1->loaded_dlls[dllindex-1])->name; + name = tcc_basename( + (dllref = pe->s1->loaded_dlls[dllindex-1]) + ->path); else name = "", dllref = NULL; @@ -884,7 +886,7 @@ static void pe_build_imports(struct pe_info *pe) if (pe->type == PE_RUN) { if (dllref) { if ( !dllref->handle ) - dllref->handle = LoadLibraryA(dllref->name); + dllref->handle = LoadLibraryA(dllref->path); v = (ADDR3264)GetProcAddress(dllref->handle, ordinal?(char*)0+ordinal:name); } if (!v) @@ -1736,7 +1738,7 @@ quit: static int pe_load_dll(TCCState *s1, int fd, const char *filename) { char *p, *q; - DLLReference *ref = tcc_add_dllref(s1, tcc_basename(filename), 0); + DLLReference *ref = tcc_add_dllref(s1, filename, 0); if (ref->found) return 0; if (get_dllexports(fd, &p))