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 <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);
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'