From a522213cc8899d4b237016aa3bbf08dc8e218f7c Mon Sep 17 00:00:00 2001 From: grischka Date: Wed, 4 Dec 2024 19:48:21 +0100 Subject: [PATCH] tccpe.c: never assume static system libtaries just clear s1->static_link before loading msvcrt etc. Also: - configure: get cc_version/name when making a cross compiler too - configure: fix android triplets - Makefile: remove CONFIG_TCC_CROSS, check TCC_TARGET_xxx instead - libtcc.c: parse some linker option arguments more correctly - tccelf.c: fix a versym problem with clang on android - lib/Makefile, build-tcc.bat: bcheck.c now includes config.h --- Makefile | 5 +++-- configure | 48 +++++++++++++++++++++++++-------------------- lib/Makefile | 4 ++-- libtcc.c | 35 ++++++++++++++++----------------- tccelf.c | 14 ++++++++++--- tccpe.c | 1 + tests/Makefile | 2 +- win32/build-tcc.bat | 2 +- 8 files changed, 63 insertions(+), 48 deletions(-) diff --git a/Makefile b/Makefile index 6fa762d7..2a7b774b 100644 --- a/Makefile +++ b/Makefile @@ -169,7 +169,6 @@ DEFINES += $(DEF-$(or $(findstring win,$T),unx)) ifneq ($(X),) $(if $(DEF-$T),,$(error error: unknown target: '$T')) -DEF-$T += -DCONFIG_TCC_CROSS DEF-$(NATIVE_TARGET) = DEF-$T += -DCONFIG_TCC_CROSSPREFIX="\"$X\"" ifneq ($(CONFIG_WIN32),yes) @@ -234,7 +233,9 @@ LIBTCC_INC = $(filter %.h %-gen.c %-link.c,$($T_FILES)) TCC_FILES = $(X)tcc.o $(LIBTCC_OBJ) $(X)tccpp.o : $(TCCDEFS_H) $(X)libtcc.o : DEFINES += -DONE_SOURCE=0 +$(CROSS_TARGET)-tcc.o : DEFINES += -DONE_SOURCE=0 endif +# native tcc always made from tcc.o and libtcc.[so|a] tcc.o : DEFINES += -DONE_SOURCE=0 DEFINES += -I$(TOP) @@ -464,7 +465,7 @@ tcov-tes% : tcc_c$(EXESUF) tcc_c$(EXESUF): $($T_FILES) $S$(TCC) tcc.c -o $@ -ftest-coverage $(DEFINES) $(LIBS) # test the installed tcc instead -test-install: tccdefs_.h +test-install: $(TCCDEFS_H) @$(MAKE) -C tests TESTINSTALL=yes #_all clean: diff --git a/configure b/configure index 05343c03..8be3d9fd 100755 --- a/configure +++ b/configure @@ -384,12 +384,12 @@ case $targetos in confvars_set Android new_dtags rpath=no test "${cpu}" != "i386" && confvars_set pie default_conf "static=no" - if test "${cpu}" = "arm"; then - default triplet "arm-linux-androideabi" - cpuver=7 - else - default triplet "${cpu}-linux-android" - fi + case "$cpu" in + arm) default triplet "arm-linux-androideabi"; cpuver=7 ;; + arm64) default triplet "aarch64-linux-android" ;; + x86_64) default triplet "x86_64-linux-android" ;; + i386) default triplet "i686-linux-android" ;; + esac test "${cpu%64}" != "${cpu}" && S="64" || S="" default tcc_sysincludepaths "{B}/include:{R}/include:{R}/include/${triplet}" default tcc_libpaths "{B}:{R}/lib:/system/lib${S}" @@ -438,17 +438,27 @@ if test x"$show_help" = "xyes" ; then show_help fi -if test -z "$build_cross"; then - CONFTEST=./conftest$EXESUF - if ! $cc -o $CONFTEST "$source_path/conftest.c" ; then +CONFTEST=./conftest$EXESUF +if test -z "$cross_prefix" \ + && $cc -o $CONFTEST "$source_path/conftest.c" \ + && $CONFTEST 2>/dev/null; then + cc_name="$($CONFTEST compiler)" + gcc_major="$($CONFTEST version)" + gcc_minor="$($CONFTEST minor)" +else + if test -z "$build_cross"; then echo "configure: error: '$cc' failed to compile conftest.c." - else - cc_name="$($CONFTEST compiler)" - gcc_major="$($CONFTEST version)" - gcc_minor="$($CONFTEST minor)" - bigendian="$($CONFTEST bigendian)" - _triplet="$($CONFTEST triplet)" fi + if test "${cc%tcc*}" != "$cc"; then + cc_name="tcc" + elif test "${cc%clang*}" != "$cc"; then + cc_name="clang" + fi +fi + +if test -z "$build_cross"; then + bigendian="$($CONFTEST bigendian)" + _triplet="$($CONFTEST triplet)" if test "$mingw32" = "no" ; then if test -z "$triplet" && test -n "$_triplet"; then if test -f "/usr/lib/$_triplet/crti.o"; then @@ -473,11 +483,6 @@ if test -z "$build_cross"; then fi else # can only make guesses about compiler and target - if test "${cc%tcc*}" != "$cc"; then - cc_name="tcc" - elif test "${cc%clang*}" != "$cc"; then - cc_name="clang" - fi case $cpu in ppc|mips|s390) bigendian=yes;; esac @@ -619,7 +624,8 @@ cat >$TMPH <-libtcc1-usegcc=yes @@ -91,7 +91,7 @@ $(X)%.o : %.S $(TCC) $(TOP)/%.o : %.c $(TCC) $S$(XCC) -c $< -o $@ $(XFLAGS) -$(TOP)/bcheck.o : XFLAGS += $(BFLAGS) +$(TOP)/bcheck.o : XFLAGS += $(BFLAGS) -I$(TOP) $(TOP)/bt-exe.o : $(TOP)/tccrun.c $(X)crt1w.o : crt1.c diff --git a/libtcc.c b/libtcc.c index 3f407c88..44cca386 100644 --- a/libtcc.c +++ b/libtcc.c @@ -1194,11 +1194,9 @@ ST_FUNC int tcc_add_dll(TCCState *s, const char *filename, int flags) /* find [cross-]libtcc1.a and tcc helper objects in library path */ ST_FUNC int tcc_add_support(TCCState *s1, const char *filename) { -#if CONFIG_TCC_CROSS char buf[100]; if (CONFIG_TCC_CROSSPREFIX[0]) filename = strcat(strcpy(buf, CONFIG_TCC_CROSSPREFIX), filename); -#endif return tcc_add_dll(s1, filename, AFF_PRINT_ERROR); } @@ -1234,11 +1232,6 @@ LIBTCCAPI int tcc_add_library(TCCState *s, const char *libraryname) return ret; ++pp; } -#if CONFIG_TCC_CROSS - /* hack for '-tcc -nostdlib -ltcc1' to find -libtcc1.a */ - if (0 == strcmp(libraryname, "tcc1")) - return tcc_add_support(s, TCC_LIBTCC1); -#endif return tcc_add_dll(s, libraryname, AFF_PRINT_ERROR); } @@ -1343,6 +1336,12 @@ static int link_option(const char *str, const char *val, const char **ptr) return ret; } +static int link_arg(const char *opt, const char *str) +{ + int l = strlen(opt); + return 0 == strncmp(opt, str, l) && (str[l] == '\0' || str[l] == ','); +} + static const char *skip_linker_arg(const char **str) { const char *s1 = *str; @@ -1410,10 +1409,10 @@ static int tcc_set_linker(TCCState *s, const char *option) if (strstart("elf32-", &p)) { #endif s->output_format = TCC_OUTPUT_FORMAT_ELF; - } else if (!strcmp(p, "binary")) { + } else if (link_arg("binary", p)) { s->output_format = TCC_OUTPUT_FORMAT_BINARY; #ifdef TCC_TARGET_COFF - } else if (!strcmp(p, "coff")) { + } else if (link_arg("coff", p)) { s->output_format = TCC_OUTPUT_FORMAT_COFF; #endif } else @@ -1446,24 +1445,24 @@ static int tcc_set_linker(TCCState *s, const char *option) s->pe_stack_size = strtoul(p, &end, 10); } else if (link_option(option, "subsystem=", &p)) { #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64) - if (strstart("native", &p)) { + if (link_arg("native", p)) { s->pe_subsystem = 1; - } else if (strstart("console", &p)) { + } else if (link_arg("console", p)) { s->pe_subsystem = 3; - } else if (strstart("gui", &p) || strstart("windows", &p)) { + } else if (link_arg("gui", p) || link_arg("windows", p)) { s->pe_subsystem = 2; - } else if (strstart("posix", &p)) { + } else if (link_arg("posix", p)) { s->pe_subsystem = 7; - } else if (strstart("efiapp", &p)) { + } else if (link_arg("efiapp", p)) { s->pe_subsystem = 10; - } else if (strstart("efiboot", &p)) { + } else if (link_arg("efiboot", p)) { s->pe_subsystem = 11; - } else if (strstart("efiruntime", &p)) { + } else if (link_arg("efiruntime", p)) { s->pe_subsystem = 12; - } else if (strstart("efirom", &p)) { + } else if (link_arg("efirom", p)) { s->pe_subsystem = 13; #elif defined(TCC_TARGET_ARM) - if (strstart("wince", &p)) { + if (link_arg("wince", p)) { s->pe_subsystem = 9; #endif } else diff --git a/tccelf.c b/tccelf.c index 304f8c69..88b4cd57 100644 --- a/tccelf.c +++ b/tccelf.c @@ -582,17 +582,24 @@ version_add (TCCState *s1) for (sym_index = 1; sym_index < end_sym; ++sym_index) { int dllindex, verndx; sym = &((ElfW(Sym) *)symtab->data)[sym_index]; - if (sym->st_shndx != SHN_UNDEF) - continue; /* defined symbol doesn't need library version */ name = (char *) symtab->link->data + sym->st_name; dllindex = find_elf_sym(s1->dynsymtab_section, name); verndx = (dllindex && dllindex < nb_sym_to_version) ? sym_to_version[dllindex] : -1; - if (verndx >= 0) { + if (verndx >= 0 + /* XXX: on android, clang refuses to link with a libtcc.so made by tcc + when defined symbols have a version > 1 or when the version is '0'. + Whereas version '1' for example for 'signal' in an exe defeats + bcheck's signal_redir. */ + && (sym->st_shndx == SHN_UNDEF || (s1->output_type & TCC_OUTPUT_EXE)) + ) { if (!sym_versions[verndx].out_index) sym_versions[verndx].out_index = nb_versions++; versym[sym_index] = sym_versions[verndx].out_index; + } else { + versym[sym_index] = 1; /* (*global*) */ } + //printf("SYM %d %s\n", versym[sym_index], name); } /* generate verneed section, but not when it will be empty. Some dynamic linkers look at their contents even when DTVERNEEDNUM and @@ -631,6 +638,7 @@ version_add (TCCState *s1) sv->out_index = -2; vna->vna_name = put_elf_str(verneed_section->link, sv->version); vna->vna_next = sizeof (*vna); + //printf("LIB %d %s %s\n", vna->vna_other, sv->lib, verneed_section->link->data + vna->vna_name); n_same_libs++; } if (prev >= 0) diff --git a/tccpe.c b/tccpe.c index 3f411c9c..a1fbb32c 100644 --- a/tccpe.c +++ b/tccpe.c @@ -1909,6 +1909,7 @@ static void pe_add_runtime(TCCState *s1, struct pe_info *pe) const char * const *pp, *p; if (TCC_LIBTCC1[0]) tcc_add_support(s1, TCC_LIBTCC1); + s1->static_link = 0; /* no static crt for tcc */ for (pp = libs; 0 != (p = *pp); ++pp) { if (*p) tcc_add_library(s1, p); diff --git a/tests/Makefile b/tests/Makefile index af363d53..db02e71e 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -318,7 +318,7 @@ CROSS-TGTS = \ define CROSS-COMPILE @echo " . $(1)" - $(TCC) $(DEF-$1) -DCONFIG_TCC_CROSS -DTCC_CROSS_TEST -run $(TOPSRC)/tcc.c \ + $(TCC) $(DEF-$1) -DTCC_CROSS_TEST -run $(TOPSRC)/tcc.c \ -c $(if $(findstring c67,$1),$(filter %/ex3.c,$^),$<) -w $(TCCFLAGS) endef diff --git a/win32/build-tcc.bat b/win32/build-tcc.bat index bcf36665..df596785 100644 --- a/win32/build-tcc.bat +++ b/win32/build-tcc.bat @@ -201,7 +201,7 @@ exit /B %ERRORLEVEL% .\tcc -B. -m%1 -c ../lib/alloca-bt.S .\tcc -B. -m%1 -c ../lib/stdatomic.c .\tcc -B. -m%1 -ar lib/%2libtcc1.a libtcc1.o crt1.o crt1w.o wincrt1.o wincrt1w.o dllcrt1.o dllmain.o chkstk.o alloca.o alloca-bt.o stdatomic.o -.\tcc -B. -m%1 -c ../lib/bcheck.c -o lib/%2bcheck.o -bt +.\tcc -B. -m%1 -c ../lib/bcheck.c -o lib/%2bcheck.o -bt -I.. .\tcc -B. -m%1 -c ../lib/bt-exe.c -o lib/%2bt-exe.o .\tcc -B. -m%1 -c ../lib/bt-log.c -o lib/%2bt-log.o .\tcc -B. -m%1 -c ../lib/bt-dll.c -o lib/%2bt-dll.o