From e844fb11c25293ba346a3470fa4ca33184770538 Mon Sep 17 00:00:00 2001 From: grischka Date: Sat, 6 Aug 2011 16:49:30 +0200 Subject: [PATCH] libtcc: support more than one crtprefix Looks like gcc has that. Oh Deer! --- configure | 2 +- libtcc.c | 57 ++++++++++++++++++++++++++++++++----------------------- tcc.h | 8 ++++---- tccelf.c | 2 +- tccpe.c | 15 --------------- 5 files changed, 39 insertions(+), 45 deletions(-) diff --git a/configure b/configure index f495ca5..546bc8a 100755 --- a/configure +++ b/configure @@ -281,7 +281,7 @@ echo " --with-selinux use mmap instead of exec mem" echo " [requires write access to /tmp]" echo " --sysincludepaths=... specify system include paths, colon separated" echo " --libpaths=... specify system library paths, colon separated" -echo " --crtprefix=... specify location of crt?.o" +echo " --crtprefix=... specify locations of crt?.o, colon separated" echo " --elfinterp=... specify elf interpreter" echo "" #echo "NOTE: The object files are build at the place where configure is launched" diff --git a/libtcc.c b/libtcc.c index a8ff87f..6a53a27 100644 --- a/libtcc.c +++ b/libtcc.c @@ -994,6 +994,8 @@ LIBTCCAPI TCCState *tcc_new(void) #ifndef TCC_TARGET_PE /* default library paths */ tcc_add_library_path(s, CONFIG_TCC_LIBPATHS); + /* paths for crt objects */ + tcc_split_path(s, (void ***)&s->crt_paths, &s->nb_crt_paths, CONFIG_TCC_CRTPREFIX); #endif /* no section zero */ @@ -1059,6 +1061,7 @@ LIBTCCAPI void tcc_delete(TCCState *s1) /* free library paths */ dynarray_reset(&s1->library_paths, &s1->nb_library_paths); + dynarray_reset(&s1->crt_paths, &s1->nb_crt_paths); /* free include paths */ dynarray_reset(&s1->cached_includes, &s1->nb_cached_includes); @@ -1225,45 +1228,51 @@ LIBTCCAPI int tcc_add_library_path(TCCState *s, const char *pathname) return 0; } -/* find and load a dll. Return non zero if not found */ -/* XXX: add '-rpath' option support ? */ -ST_FUNC int tcc_add_dll(TCCState *s, const char *filename, int flags) +static int tcc_add_library_internal(TCCState *s, const char *fmt, + const char *filename, int flags, char **paths, int nb_paths) { char buf[1024]; int i; - for(i = 0; i < s->nb_library_paths; i++) { - snprintf(buf, sizeof(buf), "%s/%s", - s->library_paths[i], filename); + for(i = 0; i < nb_paths; i++) { + snprintf(buf, sizeof(buf), fmt, paths[i], filename); if (tcc_add_file_internal(s, buf, flags) == 0) return 0; } return -1; } +/* find and load a dll. Return non zero if not found */ +/* XXX: add '-rpath' option support ? */ +ST_FUNC int tcc_add_dll(TCCState *s, const char *filename, int flags) +{ + return tcc_add_library_internal(s, "%s/%s", filename, flags, + s->library_paths, s->nb_library_paths); +} + +ST_FUNC int tcc_add_crt(TCCState *s, const char *filename) +{ + if (-1 == tcc_add_library_internal(s, "%s/%s", + filename, 0, s->crt_paths, s->nb_crt_paths)) + error_noabort("file '%s' not found", filename); + return 0; +} + /* the library name is the same as the argument of the '-l' option */ LIBTCCAPI int tcc_add_library(TCCState *s, const char *libraryname) { - char buf[1024]; - int i; - - /* first we look for the dynamic library if not static linking */ - if (!s->static_link) { #ifdef TCC_TARGET_PE - if (pe_add_dll(s, libraryname) == 0) - return 0; + const char *libs[] = { "%s/%s.def", "%s/lib%s.def", "%s/%s.dll", "%s/lib%s.dll", "%s/lib%s.a", NULL }; + const char **pp = s->static_link ? libs + 4 : libs; #else - snprintf(buf, sizeof(buf), "lib%s.so", libraryname); - if (tcc_add_dll(s, buf, 0) == 0) - return 0; + const char *libs[] = { "%s/lib%s.so", "%s/lib%s.a", NULL }; + const char **pp = s->static_link ? libs + 1 : libs; #endif - } - /* then we look for the static library */ - for(i = 0; i < s->nb_library_paths; i++) { - snprintf(buf, sizeof(buf), "%s/lib%s.a", - s->library_paths[i], libraryname); - if (tcc_add_file_internal(s, buf, 0) == 0) + while (*pp) { + if (0 == tcc_add_library_internal(s, *pp, + libraryname, 0, s->library_paths, s->nb_library_paths)) return 0; + ++pp; } return -1; } @@ -1329,8 +1338,8 @@ LIBTCCAPI int tcc_set_output_type(TCCState *s, int output_type) if ((output_type == TCC_OUTPUT_EXE || output_type == TCC_OUTPUT_DLL) && !s->nostdlib) { if (output_type != TCC_OUTPUT_DLL) - tcc_add_file(s, TCC_CRTO("crt1.o")); - tcc_add_file(s, TCC_CRTO("crti.o")); + tcc_add_crt(s, "crt1.o"); + tcc_add_crt(s, "crti.o"); } #endif return 0; diff --git a/tcc.h b/tcc.h index 70d0031..6fc3434 100644 --- a/tcc.h +++ b/tcc.h @@ -144,7 +144,7 @@ /* path to find crt1.o, crti.o and crtn.o */ #ifndef CONFIG_TCC_CRTPREFIX -# define CONFIG_TCC_CRTPREFIX "/usr" CONFIG_TCC_LDDIR +# define CONFIG_TCC_CRTPREFIX CONFIG_SYSROOT "/usr" CONFIG_TCC_LDDIR #endif /* system include paths */ @@ -190,8 +190,6 @@ /* library to use with CONFIG_USE_LIBGCC instead of libtcc1.a */ #define TCC_LIBGCC CONFIG_SYSROOT CONFIG_TCC_LDDIR "/libgcc_s.so.1" -/* crt?.o files */ -#define TCC_CRTO(crto) CONFIG_SYSROOT CONFIG_TCC_CRTPREFIX "/" crto /* -------------------------------------------- */ @@ -474,6 +472,8 @@ struct TCCState { char **library_paths; int nb_library_paths; + char **crt_paths; + int nb_crt_paths; /* array of all loaded dlls (including those referenced by loaded dlls) */ @@ -1013,6 +1013,7 @@ ST_FUNC void tcc_close(void); ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags); ST_FUNC int tcc_add_dll(TCCState *s, const char *filename, int flags); +ST_FUNC int tcc_add_crt(TCCState *s, const char *filename); PUB_FUNC int tcc_set_flag(TCCState *s, const char *flag_name, int value); PUB_FUNC void tcc_print_stats(TCCState *s, int64_t total_time); PUB_FUNC void set_num_callers(int n); @@ -1300,7 +1301,6 @@ ST_FUNC void asm_clobber(uint8_t *clobber_regs, const char *str); /* ------------ tccpe.c -------------- */ #ifdef TCC_TARGET_PE ST_FUNC int pe_load_file(struct TCCState *s1, const char *filename, int fd); -ST_FUNC int pe_add_dll(struct TCCState *s, const char *libraryname); ST_FUNC int pe_output_file(TCCState * s1, const char *filename); ST_FUNC int pe_putimport(TCCState *s1, int dllindex, const char *name, const void *value); ST_FUNC SValue *pe_getimport(SValue *sv, SValue *v2); diff --git a/tccelf.c b/tccelf.c index 47369ac..6c292d0 100644 --- a/tccelf.c +++ b/tccelf.c @@ -1247,7 +1247,7 @@ ST_FUNC void tcc_add_runtime(TCCState *s1) #endif /* add crt end if not memory output */ if (s1->output_type != TCC_OUTPUT_MEMORY) - tcc_add_file(s1, TCC_CRTO("crtn.o")); + tcc_add_crt(s1, "crtn.o"); } } diff --git a/tccpe.c b/tccpe.c index fb54523..74d0c19 100644 --- a/tccpe.c +++ b/tccpe.c @@ -1659,21 +1659,6 @@ ST_FUNC int pe_load_file(struct TCCState *s1, const char *filename, int fd) return ret; } -ST_FUNC int pe_add_dll(struct TCCState *s, const char *libname) -{ - static const char *pat[] = { - "%s.def", "lib%s.def", "%s.dll", "lib%s.dll", NULL - }; - const char **p = pat; - do { - char buf[MAX_PATH]; - snprintf(buf, sizeof(buf), *p, libname); - if (tcc_add_dll(s, buf, 0) == 0) - return 0; - } while (*++p); - return -1; -} - /* ------------------------------------------------------------- */ #ifdef TCC_TARGET_X86_64 static unsigned pe_add_uwwind_info(TCCState *s1)