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
This commit is contained in:
grischka 2020-12-16 20:08:43 +01:00
parent 02f61d5b49
commit e2e62fcb8b
13 changed files with 168 additions and 207 deletions

View File

@ -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)
# --------------------------------------------------------------------------

6
configure vendored
View File

@ -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

View File

@ -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

View File

@ -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 ();

108
libtcc.c
View File

@ -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 <TargetConditionals.h> */
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);

6
tcc.c
View File

@ -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"

36
tcc.h
View File

@ -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

View File

@ -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++) {

44
tccpe.c
View File

@ -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];

View File

@ -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"

View File

@ -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

View File

@ -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"

View File

@ -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'