diff --git a/libtcc.c b/libtcc.c index 5f27d2e4..0ffd6162 100644 --- a/libtcc.c +++ b/libtcc.c @@ -1028,6 +1028,11 @@ 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); @@ -1113,7 +1118,10 @@ LIBTCCAPI int tcc_set_output_type(TCCState *s, int output_type) #if defined(__OpenBSD__) if (output_type != TCC_OUTPUT_DLL) tcc_add_crt(s, "crt0.o"); - tcc_add_crt(s, "crtbegin.o"); + if (output_type == TCC_OUTPUT_DLL) + tcc_add_crt(s, "crtbeginS.o"); + else + tcc_add_crt(s, "crtbegin.o"); #elif defined(__FreeBSD__) if (output_type != TCC_OUTPUT_DLL) tcc_add_crt(s, "crt1.o"); @@ -1181,8 +1189,15 @@ ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags) if (s1->output_type == TCC_OUTPUT_MEMORY) { ret = 0; #ifdef TCC_IS_NATIVE - if (NULL == dlopen(filename, RTLD_GLOBAL | RTLD_LAZY)) - ret = -1; + { + 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 diff --git a/tcc.h b/tcc.h index 34ce5cd4..31b342b8 100644 --- a/tcc.h +++ b/tcc.h @@ -793,6 +793,12 @@ 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 */ diff --git a/tccelf.c b/tccelf.c index 0a569da8..856b8dcc 100644 --- a/tccelf.c +++ b/tccelf.c @@ -912,6 +912,14 @@ ST_FUNC void relocate_syms(TCCState *s1, Section *symtab, int do_resolve) void *addr = dlsym(RTLD_DEFAULT, name + 1); #else void *addr = dlsym(RTLD_DEFAULT, name); +#ifdef __OpenBSD__ + if (addr == NULL) { + int i; + for (i = 0; i < s1->nb_dlopens; i++) + if ((addr = dlsym(s1->dlopens[i], name))) + break; + } +#endif #endif if (addr) { sym->st_value = (addr_t) addr; @@ -1413,7 +1421,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__) +#if !defined(__OpenBSD__) && !defined(__NetBSD__) tcc_add_library_err(s1, "dl"); #endif tcc_add_support(s1, "bcheck.o"); @@ -1433,7 +1441,9 @@ ST_FUNC void tcc_add_runtime(TCCState *s1) tcc_add_support(s1, TCC_LIBTCC1); #if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__NetBSD__) /* add crt end if not memory output */ - if (s1->output_type != TCC_OUTPUT_MEMORY) { + 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__) tcc_add_crt(s1, "crtn.o"); diff --git a/tccpp.c b/tccpp.c index 992019fa..49c4d39f 100644 --- a/tccpp.c +++ b/tccpp.c @@ -3700,7 +3700,8 @@ 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" -#ifdef TCC_TARGET_PE +#if defined(TCC_TARGET_PE) || defined(__OpenBSD__) || \ + defined(__FreeBSD__) || defined(__NetBSD__) "#define __MAYBE_REDIR __BOTH\n" #else // HAVE MALLOC_REDIR "#define __MAYBE_REDIR __BUILTIN\n" diff --git a/tests/asm-c-connect-1.c b/tests/asm-c-connect-1.c index d79270d4..90f59c83 100644 --- a/tests/asm-c-connect-1.c +++ b/tests/asm-c-connect-1.c @@ -19,7 +19,12 @@ static int __USED x1_c (void) return 1; } +#if __i386__ asm(".text;"_"x1: call "_"x1_c; ret"); +#else +/* Keep stack aligned */ +asm(".text;"_"x1: sub $8,%rsp; call "_"x1_c; add $8,%rsp; ret"); +#endif void callx4(void); void callx5_again(void); diff --git a/tests/asm-c-connect-2.c b/tests/asm-c-connect-2.c index e2b4b595..654db0e3 100644 --- a/tests/asm-c-connect-2.c +++ b/tests/asm-c-connect-2.c @@ -22,7 +22,12 @@ int x3(void) /* That callx4 is defined globally (as if ".globl callx4") is a TCC extension. GCC doesn't behave like this. */ void callx4(void); +#if __i386__ __asm__(_"callx4: call "_"x4; ret;" +#else +/* Keep stack aligned */ +__asm__(_"callx4: sub $8,%rsp; call "_"x4; add $8,%rsp; ret;" +#endif #ifndef __TINYC__ " .global "_"callx4" #endif diff --git a/tests/pp/Makefile b/tests/pp/Makefile index 4785db3b..224c866d 100644 --- a/tests/pp/Makefile +++ b/tests/pp/Makefile @@ -12,7 +12,7 @@ TESTS = $(call files,c) $(call files,S) all test testspp.all: $(sort $(TESTS)) -DIFF_OPTS = -Nu -b -B +DIFF_OPTS = -Nu -b # Filter source directory in warnings/errors (out-of-tree builds) FILTER = 2>&1 | sed 's,$(SRC)/,,g'