From e2e62fcb8b4980903bb5729be6ea6568114885f6 Mon Sep 17 00:00:00 2001 From: grischka Date: Wed, 16 Dec 2020 20:08:43 +0100 Subject: [PATCH] replace native platform macros in the compiler - The compiler should not use these - However tccrun.c & libtcc1.a files should use these Also: - use s1->loaded_dlls for loaded dlls instead of dlopens - alpine musl: fully supported now and tested - ./configure ... --config-backtrace=no : disable backtraces --config-bcheck=no : disable bcheck - tests:dlltest: enable by default - tccrun.c : simplify mmaps - __builtin_alloca : always use asm-alias (instead of #define) - tccpe.c : use write32le --- Makefile | 5 +- configure | 6 ++- lib/Makefile | 16 +++---- lib/bcheck.c | 5 +- libtcc.c | 108 +++++++++++++++++++++--------------------- tcc.c | 6 +-- tcc.h | 36 +++++++------- tccelf.c | 71 +++++++++++++-------------- tccpe.c | 44 ++++++++--------- tccpp.c | 5 +- tccrun.c | 24 ++-------- tests/Makefile | 28 ++--------- tests/tests2/Makefile | 21 ++++---- 13 files changed, 168 insertions(+), 207 deletions(-) diff --git a/Makefile b/Makefile index 0993f82b..bb509973 100644 --- a/Makefile +++ b/Makefile @@ -94,7 +94,10 @@ NATIVE_DEFINES_$(CONFIG_arm_eabi) += -DTCC_ARM_EABI NATIVE_DEFINES_$(CONFIG_arm_vfp) += -DTCC_ARM_VFP NATIVE_DEFINES_$(CONFIG_arm64) += -DTCC_TARGET_ARM64 NATIVE_DEFINES_$(CONFIG_riscv64) += -DTCC_TARGET_RISCV64 -NATIVE_DEFINES += $(NATIVE_DEFINES_yes) +NATIVE_DEFINES_$(CONFIG_BSD) += -DTARGETOS_$(TARGETOS) +NATIVE_DEFINES_no_$(CONFIG_bcheck) += -DCONFIG_TCC_BCHECK=0 +NATIVE_DEFINES_no_$(CONFIG_backtrace) += -DCONFIG_TCC_BACKTRACE=0 +NATIVE_DEFINES += $(NATIVE_DEFINES_yes) $(NATIVE_DEFINES_no_no) ifeq ($(INCLUDED),no) # -------------------------------------------------------------------------- diff --git a/configure b/configure index 3e0ce0cb..c248d624 100755 --- a/configure +++ b/configure @@ -55,7 +55,7 @@ ar_set= targetos=`uname` case $targetos in Darwin) - confvars="$confvars OSX" + confvars="$confvars OSX dll=no" cc=`which cc` cc=`readlink $cc` tcc_usrinclude="`xcrun --show-sdk-path`/usr/include" @@ -63,9 +63,10 @@ case $targetos in ;; Windows_NT|MINGW*|MSYS*|CYGWIN*) mingw32=yes + targetos=WIN32 ;; DragonFly|OpenBSD|FreeBSD|NetBSD) - confvars="$confvars ldl=no" + confvars="$confvars BSD ldl=no" ;; *) ;; @@ -311,6 +312,7 @@ Advanced options (experts only): --elfinterp=... specify elf interpreter --triplet=... specify system library/include directory triplet --config-uClibc,-musl,-mingw32... enable system specific configurations + --config-bcheck=no/-backtrace=no disable bounds checker/stack backtraces EOF #echo "NOTE: The object files are build at the place where configure is launched" exit 1 diff --git a/lib/Makefile b/lib/Makefile index bc57be7f..2ec5f862 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -30,16 +30,16 @@ ifeq "$($(T)-libtcc1-usegcc)" "yes" XFLAGS = $(CFLAGS) -fPIC -gstabs -fno-omit-frame-pointer -Wno-unused-function -Wno-unused-variable endif +ifneq ($(CONFIG_backtrace),no) # only for native compiler +ifneq ($(CONFIG_bcheck),no) $(X)BCHECK_O = bcheck.o -$(X)BT_O = bt-exe.o bt-log.o -$(X)B_O = bcheck.o bt-exe.o bt-log.o bt-dll.o - -ifeq ($(CONFIG_musl)$(CONFIG_uClibc),yes) - BCHECK_O = -else - DSO_O = dsohandle.o endif +$(X)BT_O = bt-exe.o bt-log.o +$(X)B_O = $(BCHECK_O) bt-exe.o bt-log.o bt-dll.o +endif + +DSO_O = dsohandle.o I386_O = libtcc1.o alloca86.o alloca86-bt.o $(BT_O) X86_64_O = libtcc1.o alloca86_64.o alloca86_64-bt.o $(BT_O) @@ -82,7 +82,7 @@ $(X)%.o : %.S $(TOP)/%.o : %.c $S$(XCC) -c $< -o $@ $(XFLAGS) -$(TOP)/bcheck.o : XFLAGS += -g +$(TOP)/bcheck.o : XFLAGS += -g $(if (CONFIG_musl),-DTCC_MUSL) $(TOP)/bt-exe.o : $(TOP)/tccrun.c $(X)crt1w.o : crt1.c diff --git a/lib/bcheck.c b/lib/bcheck.c index a72efc1d..114b6e49 100644 --- a/lib/bcheck.c +++ b/lib/bcheck.c @@ -161,6 +161,9 @@ static pthread_spinlock_t bounds_spin; #define HAVE_TLS_FUNC (1) #define HAVE_TLS_VAR (0) #endif +#ifdef TCC_MUSL +# undef HAVE_CTYPE +#endif #endif #if MALLOC_REDIR @@ -1150,7 +1153,7 @@ void __attribute__((destructor)) __bound_exit(void) dprintf(stderr, "%s, %s():\n", __FILE__, __FUNCTION__); if (inited) { -#if !defined(_WIN32) && !defined(__APPLE__) && !defined(__OpenBSD__) +#if !defined(_WIN32) && !defined(__APPLE__) && !defined(__OpenBSD__) && !defined TCC_MUSL if (print_heap) { extern void __libc_freeres (void); __libc_freeres (); diff --git a/libtcc.c b/libtcc.c index 0ffd6162..8b8f8b28 100644 --- a/libtcc.c +++ b/libtcc.c @@ -880,7 +880,7 @@ LIBTCCAPI TCCState *tcc_new(void) tcc_define_symbol(s, "__linux__", NULL); tcc_define_symbol(s, "__linux", NULL); # endif -# if defined(__FreeBSD__) +# if TARGETOS_FreeBSD tcc_define_symbol(s, "__FreeBSD__", "12"); /* No 'Thread Storage Local' on FreeBSD with tcc */ tcc_define_symbol(s, "__NO_TLS", NULL); @@ -889,10 +889,10 @@ LIBTCCAPI TCCState *tcc_new(void) tcc_define_symbol(s, "__int128_t", "struct { unsigned char _dummy[16]; }"); # endif # endif -# if defined(__FreeBSD_kernel__) +# if TARGETOS_FreeBSD_kernel tcc_define_symbol(s, "__FreeBSD_kernel__", NULL); # endif -# if defined(__NetBSD__) +# if TARGETOS_NetBSD tcc_define_symbol(s, "__NetBSD__", "1"); tcc_define_symbol(s, "__GNUC__", "4"); tcc_define_symbol(s, "__GNUC_MINOR__", "0"); @@ -900,11 +900,10 @@ LIBTCCAPI TCCState *tcc_new(void) tcc_define_symbol(s, "_Pragma(x)", ""); tcc_define_symbol(s, "__ELF__", "1"); # endif -# if defined(__OpenBSD__) +# if TARGETOS_OpenBSD tcc_define_symbol(s, "__OpenBSD__", "1"); tcc_define_symbol(s, "_ANSI_LIBRARY", "1"); tcc_define_symbol(s, "__GNUC__", "4"); - tcc_define_symbol(s, "__builtin_alloca", "alloca"); /* as we claim GNUC */ /* used by math.h */ tcc_define_symbol(s, "__builtin_huge_val()", "1e500"); tcc_define_symbol(s, "__builtin_huge_valf()", "1e50f"); @@ -940,17 +939,15 @@ LIBTCCAPI TCCState *tcc_new(void) /* wint_t is unsigned int by default, but (signed) int on BSDs and unsigned short on windows. Other OSes might have still other conventions, sigh. */ -# if defined(__FreeBSD__) || defined (__FreeBSD_kernel__) \ - || defined(__NetBSD__) || defined(__OpenBSD__) +# if TARGETOS_FreeBSD || TARGETOS_FreeBSD_kernel || TARGETOS_NetBSD || TARGETOS_OpenBSD tcc_define_symbol(s, "__WINT_TYPE__", "int"); -# ifdef __FreeBSD__ +# if TARGETOS_FreeBSD /* define __GNUC__ to have some useful stuff from sys/cdefs.h that are unconditionally used in FreeBSDs other system headers :/ */ tcc_define_symbol(s, "__GNUC__", "9"); tcc_define_symbol(s, "__GNUC_MINOR__", "3"); tcc_define_symbol(s, "__GNUC_PATCHLEVEL__", "0"); tcc_define_symbol(s, "__amd64__", "1"); - tcc_define_symbol(s, "__builtin_alloca", "alloca"); # endif # else tcc_define_symbol(s, "__WINT_TYPE__", "unsigned int"); @@ -969,7 +966,6 @@ LIBTCCAPI TCCState *tcc_new(void) tcc_define_symbol(s, "__GNUC__", "4"); /* darwin emits warning on GCC<4 */ tcc_define_symbol(s, "__APPLE_CC__", "1"); /* for */ tcc_define_symbol(s, "_DONT_USE_CTYPE_INLINE_", "1"); - tcc_define_symbol(s, "__builtin_alloca", "alloca"); /* as we claim GNUC */ /* used by math.h */ tcc_define_symbol(s, "__builtin_huge_val()", "1e500"); tcc_define_symbol(s, "__builtin_huge_valf()", "1e50f"); @@ -1028,12 +1024,6 @@ LIBTCCAPI void tcc_delete(TCCState *s1) dynarray_reset(&s1->target_deps, &s1->nb_target_deps); dynarray_reset(&s1->pragma_libs, &s1->nb_pragma_libs); dynarray_reset(&s1->argv, &s1->argc); -#ifdef __OpenBSD__ - tcc_free(s1->dlopens); - s1->dlopens = NULL; - s1->nb_dlopens = 0; -#endif - cstr_free(&s1->cmdline_defs); cstr_free(&s1->cmdline_incl); #ifdef TCC_IS_NATIVE @@ -1115,24 +1105,24 @@ LIBTCCAPI int tcc_set_output_type(TCCState *s, int output_type) /* add libc crt1/crti objects */ if ((output_type == TCC_OUTPUT_EXE || output_type == TCC_OUTPUT_DLL) && !s->nostdlib) { -#if defined(__OpenBSD__) +#if TARGETOS_OpenBSD if (output_type != TCC_OUTPUT_DLL) tcc_add_crt(s, "crt0.o"); if (output_type == TCC_OUTPUT_DLL) tcc_add_crt(s, "crtbeginS.o"); else tcc_add_crt(s, "crtbegin.o"); -#elif defined(__FreeBSD__) +#elif TARGETOS_FreeBSD if (output_type != TCC_OUTPUT_DLL) tcc_add_crt(s, "crt1.o"); tcc_add_crt(s, "crti.o"); tcc_add_crt(s, "crtbegin.o"); -#elif defined(__NetBSD__) +#elif TARGETOS_NetBSD if (output_type != TCC_OUTPUT_DLL) tcc_add_crt(s, "crt0.o"); tcc_add_crt(s, "crti.o"); tcc_add_crt(s, "crtbegin.o"); -#elif !defined(TCC_TARGET_MACHO) +#elif !TCC_TARGET_MACHO /* Mach-O with LC_MAIN doesn't need any crt startup code. */ if (output_type != TCC_OUTPUT_DLL) tcc_add_crt(s, "crt1.o"); @@ -1155,16 +1145,26 @@ LIBTCCAPI int tcc_add_sysinclude_path(TCCState *s, const char *pathname) return 0; } +#if !defined TCC_TARGET_MACHO || defined TCC_IS_NATIVE +ST_FUNC DLLReference *tcc_add_dllref(TCCState *s1, const char *dllname) +{ + DLLReference *ref = tcc_mallocz(sizeof(DLLReference) + strlen(dllname)); + strcpy(ref->name, dllname); + dynarray_add(&s1->loaded_dlls, &s1->nb_loaded_dlls, ref); + return ref; +} +#endif + ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags) { - int fd, ret; + int fd, ret = -1; /* open the file */ fd = _tcc_open(s1, filename); if (fd < 0) { if (flags & AFF_PRINT_ERROR) tcc_error_noabort("file '%s' not found", filename); - return -1; + return ret; } s1->current_filename = filename; @@ -1181,55 +1181,53 @@ ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags) #endif switch (obj_type) { + case AFF_BINTYPE_REL: ret = tcc_load_object_file(s1, fd, 0); break; -#ifndef TCC_TARGET_PE - case AFF_BINTYPE_DYN: - if (s1->output_type == TCC_OUTPUT_MEMORY) { - ret = 0; -#ifdef TCC_IS_NATIVE - { - void *dl = dlopen(filename, RTLD_GLOBAL | RTLD_LAZY); - if (NULL == dl) - ret = -1; -#ifdef __OpenBSD__ - else - dynarray_add(&s1->dlopens, &s1->nb_dlopens, dl); -#endif - } -#endif - } else { -#ifndef TCC_TARGET_MACHO - ret = tcc_load_dll(s1, fd, filename, - (flags & AFF_REFERENCED_DLL) != 0); -#else - ret = macho_load_dll(s1, fd, filename, - (flags & AFF_REFERENCED_DLL) != 0); -#endif - } - break; -#endif + case AFF_BINTYPE_AR: ret = tcc_load_archive(s1, fd, !(flags & AFF_WHOLE_ARCHIVE)); break; + +#ifdef TCC_TARGET_PE + default: + ret = pe_load_file(s1, fd, filename); +#else + case AFF_BINTYPE_DYN: + if (s1->output_type == TCC_OUTPUT_MEMORY) { +#ifdef TCC_IS_NATIVE + void *dl = dlopen(filename, RTLD_GLOBAL | RTLD_LAZY); + if (dl) { + tcc_add_dllref(s1, filename)->handle = dl; + ret = 0; + } +#endif + break; + } +#ifdef TCC_TARGET_MACHO + ret = macho_load_dll(s1, fd, filename, + (flags & AFF_REFERENCED_DLL) != 0); +#else + ret = tcc_load_dll(s1, fd, filename, + (flags & AFF_REFERENCED_DLL) != 0); +#endif + break; + #ifdef TCC_TARGET_COFF case AFF_BINTYPE_C67: ret = tcc_load_coff(s1, fd); break; #endif default: -#ifdef TCC_TARGET_PE - ret = pe_load_file(s1, filename, fd); -#elif defined(TCC_TARGET_MACHO) - ret = -1; -#else +#ifndef TCC_TARGET_MACHO /* as GNU ld, consider it is an ld script if not recognized */ ret = tcc_load_ldscript(s1, fd); #endif + +#endif /* !TCC_TARGET_PE */ if (ret < 0) - tcc_error_noabort("%s: unrecognized file type %d", filename, - obj_type); + tcc_error_noabort("%s: unrecognized file type", filename); break; } close(fd); diff --git a/tcc.c b/tcc.c index b574f932..4bbb48dd 100644 --- a/tcc.c +++ b/tcc.c @@ -169,11 +169,11 @@ static const char version[] = " Windows" #elif defined(TCC_TARGET_MACHO) " Darwin" -#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) +#elif TARGETOS_FreeBSD || TARGETOS_FreeBSD_kernel " FreeBSD" -#elif defined(__OpenBSD__) +#elif TARGETOS_OpenBSD " OpenBSD" -#elif defined(__NetBSD__) +#elif TARGETOS_NetBSD " NetBSD" #else " Linux" diff --git a/tcc.h b/tcc.h index 31b342b8..ccd04ac1 100644 --- a/tcc.h +++ b/tcc.h @@ -184,13 +184,16 @@ extern long double strtold (const char *__nptr, char **__endptr); # endif #endif -#if defined TCC_IS_NATIVE && !defined CONFIG_TCCBOOT -# define CONFIG_TCC_BACKTRACE -# if (defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64 || \ - defined TCC_TARGET_ARM || defined TCC_TARGET_ARM64 || \ - defined TCC_TARGET_RISCV64) \ - && !defined TCC_UCLIBC && !defined TCC_MUSL -# define CONFIG_TCC_BCHECK /* enable bound checking code */ +#if !defined TCC_IS_NATIVE \ + || (defined CONFIG_TCC_BACKTRACE && CONFIG_TCC_BACKTRACE==0) +# undef CONFIG_TCC_BACKTRACE +# undef CONFIG_TCC_BCHECK +#else +# define CONFIG_TCC_BACKTRACE 1 +# if defined CONFIG_TCC_BCHECK && CONFIG_TCC_BCHECK==0 +# undef CONFIG_TCC_BCHECK +# else +# define CONFIG_TCC_BCHECK 1 /* enable bound checking code */ # endif #endif @@ -254,9 +257,9 @@ extern long double strtold (const char *__nptr, char **__endptr); /* name of ELF interpreter */ #ifndef CONFIG_TCC_ELFINTERP -# if defined __FreeBSD__ +# if TARGETOS_FreeBSD # define CONFIG_TCC_ELFINTERP "/libexec/ld-elf.so.1" -# elif defined __FreeBSD_kernel__ +# elif TARGETOS_FreeBSD_kernel # if defined(TCC_TARGET_X86_64) # define CONFIG_TCC_ELFINTERP "/lib/ld-kfreebsd-x86-64.so.1" # else @@ -264,7 +267,7 @@ extern long double strtold (const char *__nptr, char **__endptr); # endif # elif defined __DragonFly__ # define CONFIG_TCC_ELFINTERP "/usr/libexec/ld-elf.so.2" -# elif defined __NetBSD__ +# elif TARGETOS_NetBSD # define CONFIG_TCC_ELFINTERP "/usr/libexec/ld.elf_so" # elif defined __GNU__ # define CONFIG_TCC_ELFINTERP "/lib/ld.so" @@ -282,7 +285,7 @@ extern long double strtold (const char *__nptr, char **__endptr); # if defined(TCC_MUSL) # define CONFIG_TCC_ELFINTERP "/lib/ld-musl-x86_64.so.1" # else -# if defined(__OpenBSD__) +# if TARGETOS_OpenBSD # define CONFIG_TCC_ELFINTERP "/usr/libexec/ld.so" # else # define CONFIG_TCC_ELFINTERP "/lib64/ld-linux-x86-64.so.2" @@ -793,12 +796,6 @@ struct TCCState { char **crt_paths; int nb_crt_paths; -#ifdef __OpenBSD__ - /* track dlopen */ - void **dlopens; - int nb_dlopens; -#endif - /* -D / -U options */ CString cmdline_defs; /* -include options */ @@ -1309,6 +1306,9 @@ PUB_FUNC int tcc_parse_args(TCCState *s, int *argc, char ***argv, int optind); #ifdef _WIN32 ST_FUNC char *normalize_slashes(char *path); #endif +#if !defined TCC_TARGET_MACHO || defined TCC_IS_NATIVE +ST_FUNC DLLReference *tcc_add_dllref(TCCState *s1, const char *dllname); +#endif /* tcc_parse_args return codes: */ #define OPT_HELP 1 @@ -1743,7 +1743,7 @@ 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_load_file(struct TCCState *s1, int fd, const char *filename); ST_FUNC int pe_output_file(TCCState * s1, const char *filename); ST_FUNC int pe_putimport(TCCState *s1, int dllindex, const char *name, addr_t value); #if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64 diff --git a/tccelf.c b/tccelf.c index 856b8dcc..f4fc2826 100644 --- a/tccelf.c +++ b/tccelf.c @@ -94,7 +94,7 @@ ST_FUNC void tccelf_stab_new(TCCState *s) #ifdef CONFIG_TCC_BACKTRACE /* include stab info with standalone backtrace support */ if (s->do_backtrace && s->output_type != TCC_OUTPUT_MEMORY) - shf = SHF_ALLOC; + shf = SHF_ALLOC | SHF_WRITE; // SHF_WRITE needed for musl/SELINUX #endif stab_section = new_section(s, ".stab", SHT_PROGBITS, shf); stab_section->sh_entsize = sizeof(Stab_Sym); @@ -906,20 +906,15 @@ ST_FUNC void relocate_syms(TCCState *s1, Section *symtab, int do_resolve) /* Use ld.so to resolve symbol for us (for tcc -run) */ if (do_resolve) { #if defined TCC_IS_NATIVE && !defined TCC_TARGET_PE -#ifdef TCC_TARGET_MACHO - /* The symbols in the symtables have a prepended '_' - but dlsym() needs the undecorated name. */ - void *addr = dlsym(RTLD_DEFAULT, name + 1); -#else - void *addr = dlsym(RTLD_DEFAULT, name); -#ifdef __OpenBSD__ + /* dlsym() needs the undecorated name. */ + void *addr = dlsym(RTLD_DEFAULT, &name[s1->leading_underscore]); +#if TARGETOS_OpenBSD if (addr == NULL) { int i; - for (i = 0; i < s1->nb_dlopens; i++) - if ((addr = dlsym(s1->dlopens[i], name))) + for (i = 0; i < s1->nb_loaded_dlls; i++) + if ((addr = dlsym(s1->loaded_dlls[i]->handle, name))) break; } -#endif #endif if (addr) { sym->st_value = (addr_t) addr; @@ -1421,7 +1416,7 @@ ST_FUNC void tcc_add_runtime(TCCState *s1) #ifdef CONFIG_TCC_BCHECK if (s1->do_bounds_check && s1->output_type != TCC_OUTPUT_DLL) { tcc_add_library_err(s1, "pthread"); -#if !defined(__OpenBSD__) && !defined(__NetBSD__) +#if !TARGETOS_OpenBSD && !TARGETOS_NetBSD tcc_add_library_err(s1, "dl"); #endif tcc_add_support(s1, "bcheck.o"); @@ -1439,13 +1434,13 @@ ST_FUNC void tcc_add_runtime(TCCState *s1) #endif if (strlen(TCC_LIBTCC1) > 0) tcc_add_support(s1, TCC_LIBTCC1); -#if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__NetBSD__) +#if TARGETOS_OpenBSD || TARGETOS_FreeBSD || TARGETOS_NetBSD /* add crt end if not memory output */ if (s1->output_type == TCC_OUTPUT_DLL) tcc_add_crt(s1, "crtendS.o"); else if (s1->output_type != TCC_OUTPUT_MEMORY) { tcc_add_crt(s1, "crtend.o"); -#if defined(__FreeBSD__) || defined(__NetBSD__) +#if TARGETOS_FreeBSD || TARGETOS_NetBSD tcc_add_crt(s1, "crtn.o"); #endif } @@ -1806,7 +1801,7 @@ struct dyn_inf { unsigned long data_offset; addr_t rel_addr; addr_t rel_size; -#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) +#if TARGETOS_FreeBSD || TARGETOS_FreeBSD_kernel addr_t bss_addr; addr_t bss_size; #endif @@ -1818,23 +1813,26 @@ static int layout_sections(TCCState *s1, ElfW(Phdr) *phdr, int phnum, Section *interp, Section* strsec, struct dyn_inf *dyninf, int *sec_order) { - int i, j, k, file_type, sh_order_index, file_offset; - unsigned long s_align; - long long tmp; - addr_t addr; - ElfW(Phdr) *ph; + int i, sh_order_index, file_offset; Section *s; - file_type = s1->output_type; sh_order_index = 1; file_offset = 0; if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) file_offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr)); - s_align = ELF_PAGE_SIZE; - if (s1->section_align) - s_align = s1->section_align; - if (phnum > 0) { +#ifndef ELF_OBJ_ONLY + if (phnum > 0) { /* phnum is 0 for TCC_OUTPUT_OBJ */ + unsigned long s_align; + long long tmp; + addr_t addr; + ElfW(Phdr) *ph; + int j, k, file_type = s1->output_type; + + s_align = ELF_PAGE_SIZE; + if (s1->section_align) + s_align = s1->section_align; + if (s1->has_text_addr) { int a_offset, p_offset; addr = s1->text_addr; @@ -1863,7 +1861,7 @@ static int layout_sections(TCCState *s1, ElfW(Phdr) *phdr, int phnum, /* dynamic relocation table information, for .dynamic section */ dyninf->rel_addr = dyninf->rel_size = 0; -#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) +#if TARGETOS_FreeBSD || TARGETOS_FreeBSD_kernel dyninf->bss_addr = dyninf->bss_size = 0; #endif @@ -1934,7 +1932,7 @@ static int layout_sections(TCCState *s1, ElfW(Phdr) *phdr, int phnum, } /* update dynamic relocation infos */ if (s->sh_type == SHT_RELX) { -#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) +#if TARGETOS_FreeBSD || TARGETOS_FreeBSD_kernel if (!strcmp(strsec->data + s->sh_name, ".rel.got")) { dyninf->rel_addr = addr; dyninf->rel_size += s->sh_size; /* XXX only first rel. */ @@ -1979,6 +1977,7 @@ static int layout_sections(TCCState *s1, ElfW(Phdr) *phdr, int phnum, } } } +#endif /* ELF_OBJ_ONLY */ /* all other sections come after */ for(i = 1; i < s1->nb_sections; i++) { @@ -2080,7 +2079,7 @@ static void fill_dynamic(TCCState *s1, struct dyn_inf *dyninf) put_dt(dynamic, DT_RELA, dyninf->rel_addr); put_dt(dynamic, DT_RELASZ, dyninf->rel_size); put_dt(dynamic, DT_RELAENT, sizeof(ElfW_Rel)); -#if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__NetBSD__) +#if TARGETOS_OpenBSD || TARGETOS_FreeBSD || TARGETOS_NetBSD put_dt(dynamic, DT_PLTGOT, s1->got->sh_addr); put_dt(dynamic, DT_PLTRELSZ, dyninf->rel_size); put_dt(dynamic, DT_JMPREL, dyninf->rel_addr); @@ -2088,7 +2087,7 @@ static void fill_dynamic(TCCState *s1, struct dyn_inf *dyninf) put_dt(dynamic, DT_BIND_NOW, 1); /* Dirty hack */ #endif #else -#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) +#if TARGETOS_FreeBSD || TARGETOS_FreeBSD_kernel put_dt(dynamic, DT_PLTGOT, s1->got->sh_addr); put_dt(dynamic, DT_PLTRELSZ, dyninf->rel_size); put_dt(dynamic, DT_JMPREL, dyninf->rel_addr); @@ -2200,8 +2199,7 @@ static void tcc_output_elf(TCCState *s1, FILE *f, int phnum, ElfW(Phdr) *phdr, ehdr.e_ident[4] = ELFCLASSW; ehdr.e_ident[5] = ELFDATA2LSB; ehdr.e_ident[6] = EV_CURRENT; -#if !defined(TCC_TARGET_PE) && (defined(__FreeBSD__) || defined(__FreeBSD_kernel__)) - /* FIXME: should set only for freebsd _target_, but we exclude only PE target */ +#if TARGETOS_FreeBSD || TARGETOS_FreeBSD_kernel ehdr.e_ident[EI_OSABI] = ELFOSABI_FREEBSD; #endif #ifdef TCC_TARGET_ARM @@ -2408,7 +2406,7 @@ static void create_arm_attribute_section(TCCState *s1) } #endif -#if defined(__OpenBSD__) +#if TARGETOS_OpenBSD static Section *create_openbsd_note_section(TCCState *s1) { Section *s = find_section (s1, ".note.openbsd.ident"); @@ -2441,7 +2439,7 @@ static int elf_output_file(TCCState *s1, const char *filename) #ifdef TCC_TARGET_ARM create_arm_attribute_section (s1); #endif -#ifdef __OpenBSD__ +#if TARGETOS_OpenBSD if (file_type != TCC_OUTPUT_OBJ) note = create_openbsd_note_section (s1); #endif @@ -2766,7 +2764,7 @@ ST_FUNC int tcc_load_object_file(TCCState *s1, #ifdef TCC_ARM_EABI sh->sh_type != SHT_ARM_EXIDX && #endif -#if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__NetBSD__) +#if TARGETOS_OpenBSD || TARGETOS_FreeBSD || TARGETOS_NetBSD sh->sh_type != SHT_X86_64_UNWIND && sh->sh_type != SHT_NOTE && #endif @@ -3321,10 +3319,7 @@ ST_FUNC int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level) store_version(s1, &v, dynstr); /* add the dll and its level */ - dllref = tcc_mallocz(sizeof(DLLReference) + strlen(soname)); - dllref->level = level; - strcpy(dllref->name, soname); - dynarray_add(&s1->loaded_dlls, &s1->nb_loaded_dlls, dllref); + tcc_add_dllref(s1, soname)->level = level; /* add dynamic symbols in dynsym_section */ for(i = 1, sym = dynsym + 1; i < nb_syms; i++, sym++) { diff --git a/tccpe.c b/tccpe.c index ca210e31..3f5965fd 100644 --- a/tccpe.c +++ b/tccpe.c @@ -1277,24 +1277,10 @@ static int pe_check_symbols(struct pe_info *pe) unsigned long offset = is->thk_offset; if (offset) { /* got aliased symbol, like stricmp and _stricmp */ - } else { char buffer[100]; - WORD *p; + unsigned char *p; - offset = text_section->data_offset; - /* add the 'jmp IAT[x]' instruction */ -#ifdef TCC_TARGET_ARM - p = section_ptr_add(text_section, 8+4); // room for code and address - (*(DWORD*)(p)) = 0xE59FC000; // arm code ldr ip, [pc] ; PC+8+0 = 0001xxxx - (*(DWORD*)(p+2)) = 0xE59CF000; // arm code ldr pc, [ip] -#else - p = section_ptr_add(text_section, 8); - *p = 0x25FF; -#ifdef TCC_TARGET_X86_64 - *(DWORD*)(p+1) = (DWORD)-4; -#endif -#endif /* add a helper symbol, will be patched later in pe_build_imports */ sprintf(buffer, "IAT.%s", name); @@ -1302,16 +1288,27 @@ static int pe_check_symbols(struct pe_info *pe) symtab_section, 0, sizeof(DWORD), ELFW(ST_INFO)(STB_GLOBAL, STT_OBJECT), 0, SHN_UNDEF, buffer); + + offset = text_section->data_offset; + is->thk_offset = offset; + + /* add the 'jmp IAT[x]' instruction */ #ifdef TCC_TARGET_ARM + p = section_ptr_add(text_section, 8+4); // room for code and address + write32le(p + 0, 0xE59FC000); // arm code ldr ip, [pc] ; PC+8+0 = 0001xxxx + write32le(p + 4, 0xE59CF000); // arm code ldr pc, [ip] put_elf_reloc(symtab_section, text_section, offset + 8, R_XXX_THUNKFIX, is->iat_index); // offset to IAT position #else + p = section_ptr_add(text_section, 8); + write16le(p, 0x25FF); +#ifdef TCC_TARGET_X86_64 + write32le(p + 2, (DWORD)-4); +#endif put_elf_reloc(symtab_section, text_section, offset + 2, R_XXX_THUNKFIX, is->iat_index); #endif - is->thk_offset = offset; } - /* tcc_realloc might have altered sym's address */ sym = (ElfW(Sym) *)symtab_section->data + sym_index; @@ -1531,16 +1528,13 @@ ST_FUNC int pe_putimport(TCCState *s1, int dllindex, const char *name, addr_t va ); } -static int add_dllref(TCCState *s1, const char *dllname) +static int pe_add_dllref(TCCState *s1, const char *dllname) { - DLLReference *dllref; int i; for (i = 0; i < s1->nb_loaded_dlls; ++i) if (0 == strcmp(s1->loaded_dlls[i]->name, dllname)) return i + 1; - dllref = tcc_mallocz(sizeof(DLLReference) + strlen(dllname)); - strcpy(dllref->name, dllname); - dynarray_add(&s1->loaded_dlls, &s1->nb_loaded_dlls, dllref); + tcc_add_dllref(s1, dllname); return s1->nb_loaded_dlls; } @@ -1737,7 +1731,7 @@ static int pe_load_def(TCCState *s1, int fd) continue; case 2: - dllindex = add_dllref(s1, dllname); + dllindex = pe_add_dllref(s1, dllname); ++state; /* fall through */ default: @@ -1773,7 +1767,7 @@ static int pe_load_dll(TCCState *s1, const char *filename) if (ret) { return -1; } else if (p) { - index = add_dllref(s1, filename); + index = pe_add_dllref(s1, filename); for (q = p; *q; q += 1 + strlen(q)) pe_putimport(s1, index, q, 0); tcc_free(p); @@ -1782,7 +1776,7 @@ static int pe_load_dll(TCCState *s1, const char *filename) } /* ------------------------------------------------------------- */ -ST_FUNC int pe_load_file(struct TCCState *s1, const char *filename, int fd) +ST_FUNC int pe_load_file(struct TCCState *s1, int fd, const char *filename) { int ret = -1; char buf[10]; diff --git a/tccpp.c b/tccpp.c index 49c4d39f..3db3e566 100644 --- a/tccpp.c +++ b/tccpp.c @@ -3700,8 +3700,7 @@ static void tcc_predefs(CString *cstr) "__BOTH(char*,strcat,(char*,const char*))\n" "__BOTH(char*,strchr,(const char*,int))\n" "__BOTH(char*,strdup,(const char*))\n" -#if defined(TCC_TARGET_PE) || defined(__OpenBSD__) || \ - defined(__FreeBSD__) || defined(__NetBSD__) +#if TCC_TARGET_PE || TARGETOS_OpenBSD || TARGETOS_FreeBSD || TARGETOS_NetBSD "#define __MAYBE_REDIR __BOTH\n" #else // HAVE MALLOC_REDIR "#define __MAYBE_REDIR __BUILTIN\n" @@ -3713,6 +3712,8 @@ static void tcc_predefs(CString *cstr) "__MAYBE_REDIR(void,free,(void*))\n" #if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64 "__BOTH(void*,alloca,(__SIZE_TYPE__))\n" +#else + "__BUILTIN(void*,alloca,(__SIZE_TYPE__))\n" #endif #if defined(TCC_TARGET_ARM) && defined(TCC_ARM_EABI) "__BOUND(void*,__aeabi_memcpy,(void*,const void*,__SIZE_TYPE__))\n" diff --git a/tccrun.c b/tccrun.c index 724a5494..c216f747 100644 --- a/tccrun.c +++ b/tccrun.c @@ -91,27 +91,14 @@ LIBTCCAPI int tcc_relocate(TCCState *s1, void *ptr) int fd = mkstemp(tmpfname); unlink(tmpfname); ftruncate(fd, size); -#ifdef __OpenBSD__ -{ - int offs; + size = (size + (PAGESIZE-1)) & ~(PAGESIZE-1); - offs = (size + (0x100000-1)) & ~(0x100000-1); - prx = NULL; - ptr = mmap(NULL, size + offs, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); - if (ptr != MAP_FAILED) { - /* mmap RX memory at a fixed distance */ - munmap((char*)ptr + size, offs); - prx = mmap((char*)ptr + offs, size, PROT_READ|PROT_EXEC, MAP_SHARED|MAP_FIXED, fd, 0); - } -} -#else - ptr = mmap (NULL, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); - prx = mmap (NULL, size, PROT_READ|PROT_EXEC, MAP_SHARED, fd, 0); -#endif + ptr = mmap(NULL, size * 2, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); + /* mmap RX memory at a fixed distance */ + prx = mmap((char*)ptr + size, size, PROT_READ|PROT_EXEC, MAP_SHARED|MAP_FIXED, fd, 0); if (ptr == MAP_FAILED || prx == MAP_FAILED) tcc_error("tccrun: could not map memory"); - dynarray_add(&s1->runtime_mem, &s1->nb_runtime_mem, (void*)(addr_t)size); - dynarray_add(&s1->runtime_mem, &s1->nb_runtime_mem, prx); + dynarray_add(&s1->runtime_mem, &s1->nb_runtime_mem, (void*)(addr_t)(size*2)); ptr_diff = (char*)prx - (char*)ptr; close(fd); //printf("map %p %p %p\n", ptr, prx, (void*)ptr_diff); @@ -131,7 +118,6 @@ ST_FUNC void tcc_run_free(TCCState *s1) for (i = 0; i < s1->nb_runtime_mem; ++i) { #ifdef HAVE_SELINUX unsigned size = (unsigned)(addr_t)s1->runtime_mem[i++]; - munmap(s1->runtime_mem[i++], size); munmap(s1->runtime_mem[i], size); #else #ifdef _WIN64 diff --git a/tests/Makefile b/tests/Makefile index 0b74fbc9..371bf628 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -23,29 +23,13 @@ TESTS = \ tests2-dir \ pp-dir -BTESTS = btest test1b # test4_static -- Not all relocation types are implemented yet. # asmtest / asmtest2 -- minor differences with gcc -# bounds-checking is supported on i386 and x86_64 on linux and windows -ifeq (-$(CONFIG_musl)-, --) -ifeq ($(ARCH),i386) - TESTS += $(BTESTS) +ifneq ($(CONFIG_bcheck),no) + TESTS += btest test1b endif -ifeq ($(ARCH),x86_64) - TESTS += $(BTESTS) -endif -ifeq ($(ARCH),arm) - TESTS += $(BTESTS) -endif -ifeq ($(ARCH),arm64) - TESTS += $(BTESTS) -endif -ifeq ($(ARCH),riscv64) - TESTS += $(BTESTS) -endif -endif -ifdef CONFIG_OSX # some don't work yet +ifeq ($(CONFIG_dll),no) TESTS := $(filter-out dlltest, $(TESTS)) endif ifeq (,$(filter arm64 i386 x86_64,$(ARCH))) @@ -55,18 +39,14 @@ ifeq ($(CONFIG_arm_eabi),yes) TESTS := $(filter-out test3,$(TESTS)) endif ifeq (,$(filter i386 x86_64,$(ARCH))) - TESTS := $(filter-out dlltest asm-c-connect-test,$(TESTS)) + TESTS := $(filter-out asm-c-connect-test,$(TESTS)) endif - ifeq ($(OS),Windows_NT) # for libtcc_test to find libtcc.dll PATH := $(CURDIR)/$(TOP)$(if $(findstring ;,$(PATH)),;,:)$(PATH) endif - ifdef CONFIG_OSX LIBS += $(LINK_LIBTCC) endif - - ifeq ($(ARCH),arm) # tcctest refers to the alignment of functions, and with thumb mode # the low bit of code addresses selects the mode, so the "alignment" diff --git a/tests/tests2/Makefile b/tests/tests2/Makefile index 3d57a04d..751b17fc 100644 --- a/tests/tests2/Makefile +++ b/tests/tests2/Makefile @@ -14,7 +14,6 @@ ifeq ($(CONFIG_arm_eabi),yes) # not ARM soft-float endif ifdef CONFIG_OSX SKIP += 40_stdio.test 42_function_pointer.test - SKIP += 113_btdll.test # no shared lib support yet endif ifeq ($(ARCH),x86_64) SKIP += 73_arm64.test @@ -24,16 +23,20 @@ ifeq (,$(filter i386,$(ARCH))) endif ifeq (,$(filter i386 x86_64,$(ARCH))) SKIP += 85_asm-outside-function.test # x86 asm - SKIP += 113_btdll.test # dll support needed endif -ifeq (,$(filter i386 x86_64 arm arm64 riscv64,$(ARCH))) +ifeq ($(CONFIG_backtrace),no) SKIP += 112_backtrace.test + SKIP += 113_btdll.test + CONFIG_bcheck = no # no bcheck without backtrace +endif +ifeq ($(CONFIG_bcheck),no) SKIP += 114_bound_signal.test SKIP += 115_bound_setjmp.test SKIP += 116_bound_setjmp2.test + SKIP += 117_builtins.test endif -ifeq (-$(CONFIG_musl)-,-yes-) - SKIP += 112_backtrace.test +ifeq ($(CONFIG_dll),no) + SKIP += 113_btdll.test # no shared lib support yet endif ifeq (-$(findstring gcc,$(CC))-,--) SKIP += $(patsubst %.expect,%.test,$(GEN-ALWAYS)) @@ -45,12 +48,6 @@ ifeq (-$(CONFIG_WIN32)-,-yes-) SKIP += 106_pthread.test # No pthread support SKIP += 114_bound_signal.test # No pthread support endif -ifeq ($(TARGETOS),OpenBSD) - SKIP += 106_pthread.test - SKIP += 113_btdll.test - SKIP += 114_bound_signal.test - SKIP += 116_bound_setjmp2.test -endif # Some tests might need arguments ARGS = @@ -109,8 +106,10 @@ GEN-ALWAYS = 115_bound_setjmp.test: FLAGS += -b 116_bound_setjmp2.test: FLAGS += -b 117_builtins.test: T1 = ( $(TCC) -run $1 && $(TCC) -b -run $1 ) +ifneq ($(CONFIG_bcheck),no) 121_struct_return.test: FLAGS += -b 122_vla_reuse.test: FLAGS += -b +endif # Filter source directory in warnings/errors (out-of-tree builds) FILTER = 2>&1 | sed -e 's,$(SRC)/,,g'