From 34ead5a3b4ad0ba87723dfcec343b439a7f03936 Mon Sep 17 00:00:00 2001 From: Pepper Gray Date: Mon, 19 Oct 2026 17:12:51 +0200 Subject: [PATCH 01/20] conditional: execinfo.h Signed-off-by: Pepper Gray --- CMakeLists.txt | 24 ++++++++++++++++++++++++ src/libtools/signal32.c | 2 +- src/libtools/signals.c | 4 ++-- src/os/backtrace.c | 2 +- src/os/emit_signals_linux.c | 4 ++-- tests/CMakeLists.txt | 4 +++- 6 files changed, 33 insertions(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c74391b616..bb9d46275e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -387,6 +387,7 @@ set(BOX64_ROOT ${CMAKE_SOURCE_DIR}) add_definitions(-std=gnu11 -funwind-tables -fvisibility=hidden) add_definitions(-D_GNU_SOURCE=1) add_definitions(-D_FILE_OFFSET_BITS=64) +list(APPEND CMAKE_REQUIRED_DEFINITIONS -D_GNU_SOURCE) if(USE_CCACHE) find_program(CCACHE_FOUND ccache) @@ -418,6 +419,29 @@ add_custom_target(generate_dynacache_hashes VERBATIM ) +include(CheckIncludeFile) + +set(PROJECT_HEADERS + execinfo.h +) + +foreach(header IN LISTS PROJECT_HEADERS) + string(MAKE_C_IDENTIFIER "${header}" header_ident) + string(TOUPPER "${header_ident}" header_ident) + + set(var "HAVE_${header_ident}") + + check_include_file("${header}" "${var}") + + if(${var}) + add_compile_definitions("${var}=1") + endif() +endforeach() + +if(HAVE_EXECINFO_H AND NOT ANDROID) + add_compile_definitions(USE_BACKTRACE) +endif() + # generated files set_source_files_properties( "${BOX64_ROOT}/src/git_head.h" diff --git a/src/libtools/signal32.c b/src/libtools/signal32.c index cf16e276ea..abb1c814cb 100644 --- a/src/libtools/signal32.c +++ b/src/libtools/signal32.c @@ -12,7 +12,7 @@ #include #include #include -#ifndef ANDROID +#ifdef USE_BACKTRACE #include #endif diff --git a/src/libtools/signals.c b/src/libtools/signals.c index 8d72716325..97de60b6d7 100644 --- a/src/libtools/signals.c +++ b/src/libtools/signals.c @@ -12,7 +12,7 @@ #include #include #include -#ifndef ANDROID +#ifdef USE_BACKTRACE #include #endif @@ -1806,7 +1806,7 @@ void box64_abort() { char **strings; x64emu_t* emu = thread_get_emu(); -#ifndef ANDROID +#ifdef USE_BACKTRACE nptrs = backtrace(buffer, BT_BUF_SIZE); strings = backtrace_symbols(buffer, nptrs); if(strings) { diff --git a/src/os/backtrace.c b/src/os/backtrace.c index 327280542e..b89ccff2cc 100644 --- a/src/os/backtrace.c +++ b/src/os/backtrace.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT #include "backtrace.h" -#if !defined(ANDROID) && !defined(_WIN32) +#ifdef USE_BACKTRACE #include #include diff --git a/src/os/emit_signals_linux.c b/src/os/emit_signals_linux.c index 7e51fab15d..d8bd5826df 100644 --- a/src/os/emit_signals_linux.c +++ b/src/os/emit_signals_linux.c @@ -7,7 +7,7 @@ #include #include #include -#ifndef ANDROID +#ifdef USE_BACKTRACE #include #endif @@ -69,7 +69,7 @@ void EmitSignal(x64emu_t* emu, int sig, void* addr, int code) void* buffer[BT_BUF_SIZE]; char** strings; - #ifndef ANDROID + #ifdef USE_BACKTRACE nptrs = backtrace(buffer, BT_BUF_SIZE); strings = backtrace_symbols(buffer, nptrs); if (strings) { diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 7d523cfd2a..3cdd67bd00 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -61,7 +61,9 @@ box64_add_test(linkingIndirectNoversion 15) box64_add_test(sse_asm 16 ENV "BOX64_DYNAREC_FASTROUND=0" DISABLED_ON_ANDROID) box64_add_test(sse_intrinsics 17 ENV "BOX64_DYNAREC_FASTNAN=0;BOX64_DYNAREC_FASTROUND=0" DISABLED_ON_ANDROID) box64_add_test(aes 18) -box64_add_test(backtrace 19 DISABLED_ON_ANDROID) +IF(HAVE_EXECINFO_H) + box64_add_test(backtrace 19 DISABLED_ON_ANDROID) +ENDIF() box64_add_test(irelative_reloc 20) box64_add_test(longjumpInSignals_nocosim 21 DISABLED_ON_ANDROID) box64_add_test(x87 22 ENV "BOX64_DYNAREC_FASTROUND=0" ANDROID_REF_NUM 22_android) From a54fcdde93442c52827e5f78c48a4b6a0ebe35bc Mon Sep 17 00:00:00 2001 From: Pepper Gray Date: Mon, 19 Oct 2026 17:21:01 +0200 Subject: [PATCH 02/20] conditional: mallopt Signed-off-by: Pepper Gray --- CMakeLists.txt | 28 ++++++++++++++++++++++++++++ src/os/os_linux.c | 2 +- 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index bb9d46275e..29cb7d983a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -442,6 +442,34 @@ if(HAVE_EXECINFO_H AND NOT ANDROID) add_compile_definitions(USE_BACKTRACE) endif() +include(CheckSymbolExists) + +set(PROJECT_SYMBOL_CHECKS + mallopt malloc.h +) + +list(LENGTH PROJECT_SYMBOL_CHECKS checks_len) +math(EXPR checks_last "${checks_len} - 1") + +foreach(i RANGE 0 ${checks_last} 2) + math(EXPR j "${i} + 1") + + list(GET PROJECT_SYMBOL_CHECKS ${i} symbol) + list(GET PROJECT_SYMBOL_CHECKS ${j} header) + + string(MAKE_C_IDENTIFIER "${symbol}" symbol_ident) + string(TOUPPER "${symbol_ident}" symbol_ident) + + set(var "HAVE_${symbol_ident}") + + set(headers "${header}") + check_symbol_exists("${symbol}" "${headers}" "${var}") + + if(${var}) + add_compile_definitions("${var}=1") + endif() +endforeach() + # generated files set_source_files_properties( "${BOX64_ROOT}/src/git_head.h" diff --git a/src/os/os_linux.c b/src/os/os_linux.c index 369d6faa09..a3285c2a1b 100644 --- a/src/os/os_linux.c +++ b/src/os/os_linux.c @@ -142,7 +142,7 @@ const char* GetNativeName(void* p, int lib) void PersonalityAddrLimit32Bit(void) { personality(ADDR_LIMIT_32BIT); - #ifndef ANDROID + #if defined(HAVE_MALLOPT) && defined(M_ARENA_TEST) && defined(M_ARENA_MAX) /*struct rlimit l; if(getrlimit(RLIMIT_DATA, &l)<0) return; // failed if(l.rlim_max>3*1024*1024*1024LL) { From 7b43ab65f5f4281957060ed6be74b32c40eb5d6f Mon Sep 17 00:00:00 2001 From: Pepper Gray Date: Mon, 19 Oct 2026 18:22:24 +0200 Subject: [PATCH 03/20] conditional: malloc_trim Signed-off-by: Pepper Gray --- CMakeLists.txt | 1 + src/mallochook.c | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 29cb7d983a..78ada8a1bd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -446,6 +446,7 @@ include(CheckSymbolExists) set(PROJECT_SYMBOL_CHECKS mallopt malloc.h + malloc_trim malloc.h ) list(LENGTH PROJECT_SYMBOL_CHECKS checks_len) diff --git a/src/mallochook.c b/src/mallochook.c index ad8d28646e..7fff0fcde8 100644 --- a/src/mallochook.c +++ b/src/mallochook.c @@ -196,7 +196,9 @@ void* box32_calloc(size_t n, size_t s) void* ret = box_calloc(n, s); if(ret && FITS_IN_32BIT(ret, n * s)) return ret; box_free(ret); +#ifdef HAVE_MALLOC_TRIM malloc_trim(0); +#endif ret = box_calloc(n, s); if(ret && FITS_IN_32BIT(ret, n * s)) return ret; box_free(ret); @@ -207,7 +209,9 @@ void* box32_malloc(size_t s) void* ret = box_malloc(s); if(ret && FITS_IN_32BIT(ret, s)) return ret; box_free(ret); +#ifdef HAVE_MALLOC_TRIM malloc_trim(0); +#endif ret = box_malloc(s); if(ret && FITS_IN_32BIT(ret, s)) return ret; box_free(ret); @@ -220,7 +224,9 @@ void* box32_realloc(void* p, size_t s) void* ret = box_realloc(p, s); if(!ret) return NULL; if(FITS_IN_32BIT(ret, s)) return ret; +#ifdef HAVE_MALLOC_TRIM malloc_trim(0); +#endif void* newret = customMalloc32(s); memcpy(newret, ret, s); box_free(ret); @@ -238,7 +244,9 @@ void* box32_memalign(size_t align, size_t s) void* ret = box_memalign(align, s); if(ret && FITS_IN_32BIT(ret, s)) return ret; box_free(ret); +#ifdef HAVE_MALLOC_TRIM malloc_trim(0); +#endif return customMemAligned32(align, s); } size_t box32_malloc_usable_size(void* p) From 2aeb995ef75bbd2d02a77fb9beb23c2082b441f4 Mon Sep 17 00:00:00 2001 From: Pepper Gray Date: Mon, 19 Oct 2026 18:35:05 +0200 Subject: [PATCH 04/20] conditional: mallinfo, mallinfo2 Signed-off-by: Pepper Gray --- CMakeLists.txt | 6 ++++-- src/include/libc_malloc.h | 35 +++++++++++++++++++++++++++++++++++ src/wrapped/wrappedlibc.c | 24 ++++++++---------------- src/wrapped32/wrappedlibc.c | 34 +++++++++++++++------------------- 4 files changed, 62 insertions(+), 37 deletions(-) create mode 100644 src/include/libc_malloc.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 78ada8a1bd..d43b74e273 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -445,8 +445,10 @@ endif() include(CheckSymbolExists) set(PROJECT_SYMBOL_CHECKS - mallopt malloc.h - malloc_trim malloc.h + mallopt malloc.h + malloc_trim malloc.h + mallinfo malloc.h + mallinfo2 malloc.h ) list(LENGTH PROJECT_SYMBOL_CHECKS checks_len) diff --git a/src/include/libc_malloc.h b/src/include/libc_malloc.h new file mode 100644 index 0000000000..153268598b --- /dev/null +++ b/src/include/libc_malloc.h @@ -0,0 +1,35 @@ +// SPDX-License-Identifier: MIT +#ifndef _BOX64_LIBC_MALLOC_H_ +#define _BOX64_LIBC_MALLOC_H_ + +#ifndef HAVE_MALLINFO +struct mallinfo { + int arena; + int ordblks; + int smblks; + int hblks; + int hblkhd; + int usmblks; + int fsmblks; + int uordblks; + int fordblks; + int keepcost; +}; +#endif + +#ifndef HAVE_MALLINFO2 +struct mallinfo2 { + size_t arena; + size_t ordblks; + size_t smblks; + size_t hblks; + size_t hblkhd; + size_t usmblks; + size_t fsmblks; + size_t uordblks; + size_t fordblks; + size_t keepcost; +}; +#endif + +#endif \ No newline at end of file diff --git a/src/wrapped/wrappedlibc.c b/src/wrapped/wrappedlibc.c index 65f41f1596..25c80c381a 100644 --- a/src/wrapped/wrappedlibc.c +++ b/src/wrapped/wrappedlibc.c @@ -99,6 +99,7 @@ extern const char *const sys_siglist[] __asm__("__sys_siglist"); #include "random.h" #include "cpumask.h" #include "x64tls.h" +#include "libc_malloc.h" #ifndef LOG_INFO #define LOG_INFO 1 #endif @@ -4173,6 +4174,7 @@ EXPORT int my_posix_madvise(x64emu_t* emu, void* addr, size_t length, int advice typedef struct mallinfo (*mallinfo_fnc)(void); EXPORT void* my_mallinfo(x64emu_t* emu, void* p) { +#ifdef HAVE_MALLINFO static mallinfo_fnc f = NULL; static int inited = 0; if(!inited) { @@ -4182,26 +4184,15 @@ EXPORT void* my_mallinfo(x64emu_t* emu, void* p) if(f) *(struct mallinfo*)p=f(); else +#endif memset(p, 0, sizeof(struct mallinfo)); return p; } -struct my_mallinfo2_s { - size_t arena; - size_t ordblks; - size_t smblks; - size_t hblks; - size_t hblkhd; - size_t usmblks; - size_t fsmblks; - size_t uordblks; - size_t fordblks; - size_t keepcost; -}; - -typedef struct my_mallinfo2_s (*mallinfo2_fnc)(void); +typedef struct mallinfo2 (*mallinfo2_fnc)(void); EXPORT void* my_mallinfo2(x64emu_t* emu, void* p) { +#ifdef HAVE_MALLINFO2 static mallinfo2_fnc f = NULL; static int inited = 0; if(!inited) { @@ -4209,9 +4200,10 @@ EXPORT void* my_mallinfo2(x64emu_t* emu, void* p) f = (mallinfo2_fnc)dlsym(my_lib->w.lib, "mallinfo2"); } if(f) - *(struct my_mallinfo2_s*)p = f(); + *(struct mallinfo2*)p = f(); else - memset(p, 0, sizeof(struct my_mallinfo2_s)); +#endif + memset(p, 0, sizeof(struct mallinfo2)); return p; } diff --git a/src/wrapped32/wrappedlibc.c b/src/wrapped32/wrappedlibc.c index 71653dd567..7a36f700c7 100755 --- a/src/wrapped32/wrappedlibc.c +++ b/src/wrapped32/wrappedlibc.c @@ -49,6 +49,7 @@ #include #include #include +#include #include "wrappedlibs.h" @@ -77,6 +78,7 @@ #include "box32_inputevent.h" #include "syscall_user_dispatch.h" #include "cpumask.h" +#include "libc_malloc.h" // need to undef all read / read64 stuffs! #undef pread @@ -2500,27 +2502,21 @@ EXPORT int my32_utimensat(int dirfd, void* name, void* times, int flags) return utimensat(dirfd, name, times ? times_l : NULL, flags); } -#ifndef ANDROID -struct mallinfo { - int arena; - int ordblks; - int smblks; - int hblks; - int hblkhd; - int usmblks; - int fsmblks; - int uordblks; - int fordblks; - int keepcost; -}; -#endif - +typedef struct mallinfo (*mallinfo_fnc)(void); EXPORT void* my32_mallinfo(x86emu_t* emu, void* p) { - (void)emu; - static struct mallinfo(*p_mallinfo)() = NULL; - if(!p_mallinfo) p_mallinfo = dlsym(NULL, "mallinfo"); - *((struct mallinfo*)p) = p_mallinfo(); +#ifdef HAVE_MALLINFO + static mallinfo_fnc f = NULL; + static int inited = 0; + if(!inited) { + inited = 1; + f = (mallinfo_fnc)dlsym(my_lib->w.lib, "mallinfo"); + } + if(f) + *(struct mallinfo*)p=f(); + else +#endif + memset(p, 0, sizeof(struct mallinfo)); return p; } From 491a255d24db94a0179445a75cfb258fe6fadbff Mon Sep 17 00:00:00 2001 From: Pepper Gray Date: Mon, 19 Oct 2026 18:42:32 +0200 Subject: [PATCH 05/20] conditional: _pthread_cleanup_push/pop Signed-off-by: Pepper Gray --- CMakeLists.txt | 2 ++ src/libtools/threads.c | 4 ++++ src/libtools/threads32.c | 6 +++++- 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d43b74e273..692e4aadf7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -449,6 +449,8 @@ set(PROJECT_SYMBOL_CHECKS malloc_trim malloc.h mallinfo malloc.h mallinfo2 malloc.h + _pthread_cleanup_push pthread.h + _pthread_cleanup_pop pthread.h ) list(LENGTH PROJECT_SYMBOL_CHECKS checks_len) diff --git a/src/libtools/threads.c b/src/libtools/threads.c index 08317ed40c..8a147214b7 100644 --- a/src/libtools/threads.c +++ b/src/libtools/threads.c @@ -49,8 +49,12 @@ typedef struct emuthread_s emuthread_t; static vFppp_t real_pthread_cleanup_push_defer = NULL; static vFpi_t real_pthread_cleanup_pop_restore = NULL; static iFppip_t real_pthread_cond_clockwait = NULL; +#ifndef HAVE__PTHREAD_CLEANUP_PUSH void _pthread_cleanup_push(void* buffer, void* routine, void* arg); // declare hidden functions +#endif +#ifndef HAVE__PTHREAD_CLEANUP_POP void _pthread_cleanup_pop(void* buffer, int exec); +#endif // with glibc 2.34+, pthread_kill changed behaviour and might break some program, so using old version if possible // it will be pthread_kill@GLIBC_2.17 on aarch64, but it's GLIBC_2.2.5 on x86_64 static iFli_t real_phtread_kill_old = NULL; diff --git a/src/libtools/threads32.c b/src/libtools/threads32.c index c03e31585e..6c12fd7816 100755 --- a/src/libtools/threads32.c +++ b/src/libtools/threads32.c @@ -52,8 +52,12 @@ static vFpi_t real_pthread_cleanup_pop_restore = NULL; static iFLi_t real_phtread_kill_old = NULL; static iFv_t real_pthread_yield = NULL; // those function can be used simply -void _pthread_cleanup_push(void* buffer, void* routine, void* arg); // declare hidden functions +#ifndef HAVE__PTHREAD_CLEANUP_PUSH +void _pthread_cleanup_push(void* buffer, void* routine, void* arg); // declare hidden functions +#endif +#ifndef HAVE__PTHREAD_CLEANUP_POP void _pthread_cleanup_pop(void* buffer, int exec); +#endif typedef struct threadstack_s { void* stack; From b6a86e9b6fecdd3e978299e98adb9cd52c460e29 Mon Sep 17 00:00:00 2001 From: Pepper Gray Date: Mon, 19 Oct 2026 18:55:48 +0200 Subject: [PATCH 06/20] conditional: pthread_attr_get/setaffinity_np Signed-off-by: Pepper Gray --- CMakeLists.txt | 3 +++ src/libtools/signals.c | 13 ++++++++++++- src/libtools/threads.c | 6 ++++-- src/libtools/threads32.c | 4 ++++ 4 files changed, 23 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 692e4aadf7..4abc1d1033 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -451,6 +451,9 @@ set(PROJECT_SYMBOL_CHECKS mallinfo2 malloc.h _pthread_cleanup_push pthread.h _pthread_cleanup_pop pthread.h + pthread_attr_getaffinity_np pthread.h + pthread_attr_setaffinity_np pthread.h + pthread_mutexattr_setprioceiling pthread.h ) list(LENGTH PROJECT_SYMBOL_CHECKS checks_len) diff --git a/src/libtools/signals.c b/src/libtools/signals.c index 97de60b6d7..45639ebd4b 100644 --- a/src/libtools/signals.c +++ b/src/libtools/signals.c @@ -824,8 +824,10 @@ extern int fillblock_active; #ifdef USE_SIGNAL_MUTEX #ifdef USE_CUSTOM_MUTEX static uint32_t mutex_dynarec_prot = 0; -#else +#elif defined(PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP) static pthread_mutex_t mutex_dynarec_prot = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP; +#else +static pthread_mutex_t mutex_dynarec_prot = PTHREAD_MUTEX_INITIALIZER; #endif #define lock_signal() mutex_lock(&mutex_dynarec_prot) #define unlock_signal() mutex_unlock(&mutex_dynarec_prot) @@ -1847,8 +1849,17 @@ static void atfork_child_dynarec_prot(void) #ifdef USE_CUSTOM_MUTEX native_lock_store(&mutex_dynarec_prot, 0); #else + #ifdef PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP pthread_mutex_t tmp = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP; memcpy(&mutex_dynarec_prot, &tmp, sizeof(mutex_dynarec_prot)); + #else + pthread_mutex_t tmp = PTHREAD_MUTEX_INITIALIZER; + pthread_mutexattr_t attr; + pthread_mutexattr_init(&attr); + pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK); + pthread_mutex_init(&mutex_dynarec_prot, &attr); + pthread_mutexattr_destroy(&attr); + #endif #endif } #endif diff --git a/src/libtools/threads.c b/src/libtools/threads.c index 8a147214b7..7e4325f34d 100644 --- a/src/libtools/threads.c +++ b/src/libtools/threads.c @@ -478,7 +478,7 @@ EXPORT int my_pthread_attr_init(x64emu_t* emu, pthread_attr_t* attr) PTHREAD_ATTR_UNALIGN(attr); return ret; } -#ifndef ANDROID +#ifdef HAVE_PTHREAD_ATTR_GETAFFINITY_NP EXPORT int my_pthread_attr_getaffinity_np(x64emu_t* emu, pthread_attr_t* attr, size_t cpusize, void* cpuset) { (void)emu; @@ -491,6 +491,8 @@ EXPORT int my_pthread_attr_getaffinity_np(x64emu_t* emu, pthread_attr_t* attr, s } return ret; } +#endif +#ifdef HAVE_PTHREAD_ATTR_SETAFFINITY_NP EXPORT int my_pthread_attr_setaffinity_np(x64emu_t* emu, pthread_attr_t* attr, size_t cpusize, void* cpuset) { (void)emu; @@ -1093,7 +1095,7 @@ EXPORT int my_pthread_mutexattr_setkind_np(x64emu_t* emu, my_mutexattr_t *attr, } EXPORT int my_pthread_mutexattr_setprioceiling(x64emu_t* emu, my_mutexattr_t *attr, int p) { -#if !defined(TERMUX) && !defined(ANDROID) +#ifdef HAVE_PTHREAD_MUTEXATTR_SETPRIOCEILING (void)emu; my_mutexattr_t mattr = {0}; mattr.x86 = attr->x86; diff --git a/src/libtools/threads32.c b/src/libtools/threads32.c index 6c12fd7816..92e1f3823a 100755 --- a/src/libtools/threads32.c +++ b/src/libtools/threads32.c @@ -887,6 +887,7 @@ EXPORT int my32_pthread_setaffinity_np(x64emu_t* emu, pthread_t thread, int cpus return ret; } +#ifdef HAVE_PTHREAD_ATTR_SETAFFINITY_NP EXPORT int my32_pthread_attr_setaffinity_np(x64emu_t* emu, void* attr, uint32_t cpusetsize, void* cpuset) { if(cpusetsize>0x1000) { @@ -908,6 +909,8 @@ EXPORT int my32_pthread_attr_setaffinity_np(x64emu_t* emu, void* attr, uint32_t return ret; } +#endif +#ifdef HAVE_PTHREAD_ATTR_GETAFFINITY_NP EXPORT int my32_pthread_attr_getaffinity_np(x64emu_t* emu, void* attr, uint32_t cpusetsize, void* cpuset) { if(cpusetsize>0x1000) { @@ -922,6 +925,7 @@ EXPORT int my32_pthread_attr_getaffinity_np(x64emu_t* emu, void* attr, uint32_t } return ret; } +#endif #endif From ed3e32cadd0e60f35db92a7ab28d767b1a10bd20 Mon Sep 17 00:00:00 2001 From: Pepper Gray Date: Tue, 20 Oct 2026 04:29:20 +0200 Subject: [PATCH 07/20] conditional: __pthread_mutex_s->__kind my32_pthread_mutex_init: fake->i386__kind: incomplete definition of type 'struct __pthread_mutex_s' Signed-off-by: Pepper Gray --- src/libtools/threads32.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/libtools/threads32.c b/src/libtools/threads32.c index 92e1f3823a..52003d88df 100755 --- a/src/libtools/threads32.c +++ b/src/libtools/threads32.c @@ -1064,7 +1064,14 @@ EXPORT int my32_pthread_mutex_init(pthread_mutex_t *m, pthread_mutexattr_t *att) fake->__kind = KIND_SIGN; fake->real_mutex = to_ptrv(createNewMutex()); int ret = pthread_mutex_init(from_ptrv(fake->real_mutex), att); +#ifdef __GLIBC__ fake->i386__kind = ((struct __pthread_mutex_s*)from_ptrv(fake->real_mutex))->__kind; +#else + // reads only the basic mutex type & fails silently + int kind = PTHREAD_MUTEX_NORMAL; + if(att) pthread_mutexattr_gettype(att, &kind); + fake->i386__kind = kind; +#endif printf_log(LOG_DEBUG, "(init t%d %p) ", fake->i386__kind, from_ptrv(fake->real_mutex)); return ret; } From 7d5f8c9c18eca39908758a8b1e48799491cb19d3 Mon Sep 17 00:00:00 2001 From: Pepper Gray Date: Mon, 19 Oct 2026 18:59:15 +0200 Subject: [PATCH 08/20] conditional: dlvsym Signed-off-by: Pepper Gray --- CMakeLists.txt | 1 + src/libtools/threads.c | 2 ++ src/libtools/threads32.c | 2 ++ 3 files changed, 5 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4abc1d1033..20677ac307 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -454,6 +454,7 @@ set(PROJECT_SYMBOL_CHECKS pthread_attr_getaffinity_np pthread.h pthread_attr_setaffinity_np pthread.h pthread_mutexattr_setprioceiling pthread.h + dlvsym dlfcn.h ) list(LENGTH PROJECT_SYMBOL_CHECKS checks_len) diff --git a/src/libtools/threads.c b/src/libtools/threads.c index 7e4325f34d..724a0aacff 100644 --- a/src/libtools/threads.c +++ b/src/libtools/threads.c @@ -1457,6 +1457,7 @@ void init_pthread_helper() // search for older symbol for pthread_kill { +#ifdef HAVE_DLVSYM char buff[50]; for(int i=0; i<34 && !real_phtread_kill_old; ++i) { snprintf(buff, 50, "GLIBC_2.%d", i); @@ -1467,6 +1468,7 @@ void init_pthread_helper() real_phtread_kill_old = (iFli_t)dlvsym(NULL, "pthread_kill", "GLIBC_2.2.5"); if(!real_phtread_kill_old) { printf_log(LOG_INFO, "Warning, older then 2.34 pthread_kill not found, using current one\n"); +#endif real_phtread_kill_old = (iFli_t)pthread_kill; } diff --git a/src/libtools/threads32.c b/src/libtools/threads32.c index 52003d88df..fa44f15af5 100755 --- a/src/libtools/threads32.c +++ b/src/libtools/threads32.c @@ -1116,6 +1116,7 @@ void init_pthread_helper_32() // search for older symbol for pthread_kill { +#ifdef HAVE_DLVSYM char buff[50]; for(int i=0; i<34 && !real_phtread_kill_old; ++i) { snprintf(buff, 50, "GLIBC_2.%d", i); @@ -1124,6 +1125,7 @@ void init_pthread_helper_32() } if(!real_phtread_kill_old) { printf_log(LOG_INFO, "Warning, older than 2.34 pthread_kill not found, using current one\n"); +#endif real_phtread_kill_old = (iFLi_t)pthread_kill; } // pthread_yield (or sched_yield if not found) From 4aad99a7e35eb7e8db3a9c600608c0a298c73acf Mon Sep 17 00:00:00 2001 From: Pepper Gray Date: Mon, 19 Oct 2026 19:07:23 +0200 Subject: [PATCH 09/20] conditional: obstack_vprintf Signed-off-by: Pepper Gray --- CMakeLists.txt | 2 ++ src/include/libc_obstack.h | 9 ++++++++ src/libtools/libc.c | 44 ++++++++++++++++++++++++++++++++++++++ src/libtools/obstack.c | 1 + 4 files changed, 56 insertions(+) create mode 100644 src/include/libc_obstack.h create mode 100644 src/libtools/libc.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 20677ac307..e01263d070 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -455,6 +455,7 @@ set(PROJECT_SYMBOL_CHECKS pthread_attr_setaffinity_np pthread.h pthread_mutexattr_setprioceiling pthread.h dlvsym dlfcn.h + obstack_vprintf stdio.h ) list(LENGTH PROJECT_SYMBOL_CHECKS checks_len) @@ -538,6 +539,7 @@ set(ELFLOADER_SRC "${BOX64_ROOT}/src/libtools/syscall_user_dispatch.c" "${BOX64_ROOT}/src/libtools/decopcode.c" "${BOX64_ROOT}/src/libtools/threads.c" + "${BOX64_ROOT}/src/libtools/libc.c" "${BOX64_ROOT}/src/steamwebhelper.c" "${BOX64_ROOT}/src/tools/bitutils.c" "${BOX64_ROOT}/src/tools/box64stack.c" diff --git a/src/include/libc_obstack.h b/src/include/libc_obstack.h new file mode 100644 index 0000000000..690ba0dd7f --- /dev/null +++ b/src/include/libc_obstack.h @@ -0,0 +1,9 @@ +// SPDX-License-Identifier: MIT +#ifndef _BOX64_LIBC_OBSTACK_H_ +#define _BOX64_LIBC_OBSTACK_H_ + +#ifndef HAVE_OBSTACK_VPRINTF +int obstack_vprintf(struct obstack *obstack, const char *fmt, va_list args); +#endif + +#endif \ No newline at end of file diff --git a/src/libtools/libc.c b/src/libtools/libc.c new file mode 100644 index 0000000000..df45e7b75a --- /dev/null +++ b/src/libtools/libc.c @@ -0,0 +1,44 @@ +// SPDX-License-Identifier: MIT +#include +#include +#include + + +#if !defined(HAVE_OBSTACK_VPRINTF) && !defined(ANDROID) +#include + +int obstack_vprintf(struct obstack *obstack, const char *fmt, va_list args) +{ + char buffer[200]; + char *buf = buffer; + va_list copy; + + va_copy(copy, args); + int len = vsnprintf(buffer, sizeof(buffer), fmt, copy); + va_end(copy); + + if (len < 0) return -1; + + if ((size_t)len >= sizeof(buffer)) + { + buf = malloc((size_t)len + 1); + if (!buf) return -1; + + va_copy(copy, args); + int n = vsnprintf(buf, len + 1, fmt, copy); + va_end(copy); + + if (n != len) + { + free(buf); + return -1; + } + len = n; + } + + if(len > 0) obstack_grow(obstack, buf, len); + if(buf != buffer) free(buf); + + return len; +} +#endif \ No newline at end of file diff --git a/src/libtools/obstack.c b/src/libtools/obstack.c index 4b40fee618..2ac435c349 100644 --- a/src/libtools/obstack.c +++ b/src/libtools/obstack.c @@ -27,6 +27,7 @@ #ifdef BOX32 #include "myalign32.h" #endif +#include "libc_obstack.h" typedef void (*vFv_t) (); typedef int32_t (*iFppp_t) (void*, void*, void*); From 10e8e0cf9c5ec1327975b23100c236742276b812 Mon Sep 17 00:00:00 2001 From: Pepper Gray Date: Mon, 19 Oct 2026 19:45:56 +0200 Subject: [PATCH 10/20] conditional: struct obstack Signed-off-by: Pepper Gray --- CMakeLists.txt | 19 +++++++++++++++++++ src/libtools/myalign32.c | 12 ++++++------ 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e01263d070..11d6bc13b3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -480,6 +480,25 @@ foreach(i RANGE 0 ${checks_last} 2) endif() endforeach() +include(CheckCSourceCompiles) + +check_c_source_compiles("#include +int main(void){ struct obstack o = { .temp.tempptr = NULL }; return 0; }" OBSTACK_TEMP_TEMPPTR) +check_c_source_compiles("#include +int main(void){ struct obstack o = { .temp.p = NULL }; return 0; }" OBSTACK_TEMP_P) + +if(OBSTACK_TEMP_TEMPPTR) # glibc + add_compile_definitions("STRUCT_OBSTACK_TEMP=tempptr") + add_compile_definitions("STRUCT_OBSTACK_CHUNKFUN=chunkfun") + add_compile_definitions("STRUCT_OBSTACK_FREEFUN=freefun") +elseif(OBSTACK_TEMP_P) # musl-obstack + add_compile_definitions("STRUCT_OBSTACK_TEMP=p") + add_compile_definitions("STRUCT_OBSTACK_CHUNKFUN=chunkfun.extra") + add_compile_definitions("STRUCT_OBSTACK_FREEFUN=freefun.extra") +elseif(NOT ANDROID) + message(FATAL_ERROR "Unknown struct obstack layout!") +endif() + # generated files set_source_files_properties( "${BOX64_ROOT}/src/git_head.h" diff --git a/src/libtools/myalign32.c b/src/libtools/myalign32.c index eae303f017..d1e9979a37 100755 --- a/src/libtools/myalign32.c +++ b/src/libtools/myalign32.c @@ -1508,9 +1508,9 @@ void convert_obstack_to_32(void* d, void* s) dst->object_base = to_ptrv(src->object_base); dst->next_free = to_ptrv(src->next_free); dst->chunk_limit = to_ptrv(src->chunk_limit); - dst->temp.tempptr = to_ptrv(src->temp.tempptr); - dst->chunkfun = to_ptrv(src->chunkfun); - dst->freefun = to_ptrv(src->freefun); + dst->temp.tempptr = to_ptrv(src->temp.STRUCT_OBSTACK_TEMP); + dst->chunkfun = to_ptrv(src->STRUCT_OBSTACK_CHUNKFUN); + dst->freefun = to_ptrv(src->STRUCT_OBSTACK_FREEFUN); dst->extra_arg = to_ptrv(src->extra_arg); dst->use_extra_arg = src->use_extra_arg; dst->maybe_empty_object = src->maybe_empty_object; @@ -1526,9 +1526,9 @@ void convert_obstack_to_64(void* d, void* s) dst->maybe_empty_object = src->maybe_empty_object; dst->use_extra_arg = src->use_extra_arg; dst->extra_arg = from_ptrv(src->extra_arg); - dst->freefun = from_ptrv(src->freefun); - dst->chunkfun = from_ptrv(src->chunkfun); - dst->temp.tempptr = from_ptrv(src->temp.tempptr); + dst->STRUCT_OBSTACK_FREEFUN = from_ptrv(src->freefun); + dst->STRUCT_OBSTACK_CHUNKFUN = from_ptrv(src->chunkfun); + dst->temp.STRUCT_OBSTACK_TEMP = from_ptrv(src->temp.tempptr); dst->chunk_limit = from_ptrv(src->chunk_limit); dst->next_free = from_ptrv(src->next_free); dst->object_base = from_ptrv(src->object_base); From 43dda3f952e18e2b8ce5e5835be890ab07204859 Mon Sep 17 00:00:00 2001 From: Pepper Gray Date: Mon, 19 Oct 2026 19:56:18 +0200 Subject: [PATCH 11/20] conditional: siginfo_t Signed-off-by: Pepper Gray --- CMakeLists.txt | 13 +++++++++++++ src/include/signals.h | 4 ++++ src/libtools/signal32.c | 2 +- 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 11d6bc13b3..3b72d66705 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -499,6 +499,19 @@ elseif(NOT ANDROID) message(FATAL_ERROR "Unknown struct obstack layout!") endif() +check_c_source_compiles("#include +int main(void){ siginfo_t s = { ._sifields = { 0 } }; return 0; }" SIGINFO_S__SIFIELDS) +check_c_source_compiles("#include +int main(void){ siginfo_t s = { .__si_fields = { 0 } }; return 0; }" SIGINFO_S___SI_FIELDS) + +if(SIGINFO_S__SIFIELDS) # glibc + add_compile_definitions("SIGINFO_S_SIFIELDS=_sifields") +elseif(SIGINFO_S___SI_FIELDS) # musl + add_compile_definitions("SIGINFO_S_SIFIELDS=__si_fields") +elseif(NOT ANDROID) + message(FATAL_ERROR "Unknown siginfo_t layout!") +endif() + # generated files set_source_files_properties( "${BOX64_ROOT}/src/git_head.h" diff --git a/src/include/signals.h b/src/include/signals.h index 23626a3cfd..fd12b57292 100644 --- a/src/include/signals.h +++ b/src/include/signals.h @@ -6,6 +6,10 @@ #include "x64_signals.h" #include "box64context.h" +#ifndef __SI_SIGFAULT_ADDL +#define __SI_SIGFAULT_ADDL +#endif + typedef void (*sighandler_t)(int); #ifdef ANDROID diff --git a/src/libtools/signal32.c b/src/libtools/signal32.c index abb1c814cb..c1e9c4ea20 100644 --- a/src/libtools/signal32.c +++ b/src/libtools/signal32.c @@ -450,7 +450,7 @@ void convert_siginfo_to_32(void* d, void* s, int sig) dst->si_signo = src->si_signo; dst->si_errno = src->si_errno; dst->si_code = src->si_code; - memcpy(&dst->_sifields, &src->_sifields, sizeof(siginfo_t) - offsetof(siginfo_t, _sifields)); + memcpy(&dst->_sifields, &src->SIGINFO_S_SIFIELDS, sizeof(siginfo_t) - offsetof(siginfo_t, SIGINFO_S_SIFIELDS)); if(sig==X64_SIGILL || sig==X64_SIGFPE || sig==X64_SIGSEGV || sig==X64_SIGBUS) dst->_sifields._sigfault.__si_addr = to_ptr(((uintptr_t)src->si_addr)&0xffffffff); // in case addr is not a 32bits value... if(sig==X64_SIGCHLD) { From 5ae453ab8f01ff1271893ac5260d71bfad9b0e31 Mon Sep 17 00:00:00 2001 From: Pepper Gray Date: Mon, 19 Oct 2026 20:34:49 +0200 Subject: [PATCH 12/20] conditional: getprotobyname/number_r Signed-off-by: Pepper Gray --- CMakeLists.txt | 2 + src/include/libc_netdb.h | 13 ++++++ src/libtools/libc.c | 86 ++++++++++++++++++++++++++++++++++++++- src/libtools/libc_net32.c | 1 + 4 files changed, 101 insertions(+), 1 deletion(-) create mode 100644 src/include/libc_netdb.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 3b72d66705..e84af23896 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -456,6 +456,8 @@ set(PROJECT_SYMBOL_CHECKS pthread_mutexattr_setprioceiling pthread.h dlvsym dlfcn.h obstack_vprintf stdio.h + getprotobyname_r netdb.h + getprotobynumber_r netdb.h ) list(LENGTH PROJECT_SYMBOL_CHECKS checks_len) diff --git a/src/include/libc_netdb.h b/src/include/libc_netdb.h new file mode 100644 index 0000000000..8656b08d21 --- /dev/null +++ b/src/include/libc_netdb.h @@ -0,0 +1,13 @@ +// SPDX-License-Identifier: MIT +#ifndef _BOX64_LIBC_NETDB_H_ +#define _BOX64_LIBC_NETDB_H_ + +#ifndef HAVE_GETPROTOBYNAME_R +int getprotobyname_r(const char *name, struct protoent *result_buf, char *buf, size_t buflen, struct protoent **result); +#endif + +#ifndef HAVE_GETPROTOBYNUMBER_R +int getprotobynumber_r(int proto, struct protoent *result_buf, char *buf, size_t buflen, struct protoent **result); +#endif + +#endif \ No newline at end of file diff --git a/src/libtools/libc.c b/src/libtools/libc.c index df45e7b75a..daa46eaec0 100644 --- a/src/libtools/libc.c +++ b/src/libtools/libc.c @@ -2,6 +2,12 @@ #include #include #include +#include +#include +#include +#include +#include +#include #if !defined(HAVE_OBSTACK_VPRINTF) && !defined(ANDROID) @@ -41,4 +47,82 @@ int obstack_vprintf(struct obstack *obstack, const char *fmt, va_list args) return len; } -#endif \ No newline at end of file +#endif + +#if ! defined(HAVE_GETPROTOBYNAME_R) || ! defined(HAVE_GETPROTOBYNUMBER_R) + +static pthread_mutex_t mutex_getproto = PTHREAD_MUTEX_INITIALIZER; + +static int copyprotoent(const struct protoent *src, struct protoent *result_buf, char *buf, size_t buflen, struct protoent **result) +{ + size_t size_buf = 0; + char *ptr = buf; + *result = NULL; + + if(!src) return 0; + + // official protocol name + size_t size_name = (strlen(src->p_name) + 1) * sizeof(char); + size_buf += size_name; + if(size_buf > buflen) return ERANGE; + memcpy(ptr, src->p_name, size_name); + result_buf->p_name = ptr; + ptr += size_name; + + // padding + size_t align = _Alignof(char *); + size_t pad_len = (align - (uintptr_t)ptr % align) % align; + size_buf += pad_len; + if(size_buf > buflen) return ERANGE; + ptr += pad_len; + + // alias list + size_t num_aliases = 0; + while(src->p_aliases[num_aliases]) num_aliases++; + size_t size_aliases = (num_aliases + 1) * sizeof(char*); + size_buf += size_aliases; + if(size_buf > buflen) return ERANGE; + char **aliases = (char **) ptr; + aliases[num_aliases] = NULL; + result_buf->p_aliases = aliases; + ptr += size_aliases; + + // aliases + for(size_t i = 0; i < num_aliases; i++) + { + size_t size_alias = (strlen(src->p_aliases[i]) + 1) * sizeof(char); + size_buf += size_alias; + if(size_buf > buflen) return ERANGE; + memcpy(ptr, src->p_aliases[i], size_alias); + aliases[i] = ptr; + ptr += size_alias; + } + + // protocol number + result_buf->p_proto = src->p_proto; + + // done + *result = result_buf; + return 0; +} + +#ifndef HAVE_GETPROTOBYNAME_R +int getprotobyname_r(const char *name, struct protoent *result_buf, char *buf, size_t buflen, struct protoent **result) +{ + pthread_mutex_lock(&mutex_getproto); + int res = copyprotoent(getprotobyname(name), result_buf, buf, buflen, result); + pthread_mutex_unlock(&mutex_getproto); + return res; +} +#endif + +#ifndef HAVE_GETPROTOBYNUMBER_R +int getprotobynumber_r(int proto, struct protoent *result_buf, char *buf, size_t buflen, struct protoent **result) +{ + pthread_mutex_lock(&mutex_getproto); + int res = copyprotoent(getprotobynumber(proto), result_buf, buf, buflen, result); + pthread_mutex_unlock(&mutex_getproto); + return res; +} +#endif +#endif diff --git a/src/libtools/libc_net32.c b/src/libtools/libc_net32.c index aac38a317a..d48dead106 100644 --- a/src/libtools/libc_net32.c +++ b/src/libtools/libc_net32.c @@ -39,6 +39,7 @@ #include "box32.h" #include "converter32.h" #include "custommem.h" +#include "libc_netdb.h" EXPORT ssize_t my32_recvmsg(x64emu_t* emu, int socket, struct i386_msghdr* msg, int flags) { From 425ef9182d7af0b63c251759708a55afbd83447c Mon Sep 17 00:00:00 2001 From: Pepper Gray Date: Mon, 19 Oct 2026 20:36:48 +0200 Subject: [PATCH 13/20] conditional: struct __res_state Signed-off-by: Pepper Gray --- CMakeLists.txt | 15 +++++++++++++++ src/libtools/libc_net32.c | 8 ++++---- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e84af23896..557ec72a10 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -514,6 +514,21 @@ elseif(NOT ANDROID) message(FATAL_ERROR "Unknown siginfo_t layout!") endif() +check_c_source_compiles("#include +int main(void){ struct __res_state r = { .__glibc_unused_qhook = NULL }; return 0; }" RES_STATE_GLIBC_UNUSED_QHOOK) +check_c_source_compiles("#include +int main(void){ struct __res_state r = { .qhook = NULL }; return 0; }" RES_STATE_QHOOK) + +if(RES_STATE_GLIBC_UNUSED_QHOOK) # glibc + add_compile_definitions("RES_STATE_QHOOK=__glibc_unused_qhook") + add_compile_definitions("RES_STATE_RHOOK=__glibc_unused_rhook") +elseif(RES_STATE_QHOOK) # musl + add_compile_definitions("RES_STATE_QHOOK=qhook") + add_compile_definitions("RES_STATE_RHOOK=rhook") +elseif(NOT ANDROID) + message(FATAL_ERROR "Unknown res_state layout!") +endif() + # generated files set_source_files_properties( "${BOX64_ROOT}/src/git_head.h" diff --git a/src/libtools/libc_net32.c b/src/libtools/libc_net32.c index d48dead106..60afaa9636 100644 --- a/src/libtools/libc_net32.c +++ b/src/libtools/libc_net32.c @@ -599,8 +599,8 @@ void* convert_res_state_to_32(void* d, void* s) dst->ipv6_unavail = src->ipv6_unavail; dst->unused = src->unused; memmove(dst->sort_list, src->sort_list, sizeof(dst->sort_list)); - dst->__glibc_unused_qhook = to_ptrv(src->__glibc_unused_qhook); - dst->__glibc_unused_rhook = to_ptrv(src->__glibc_unused_rhook); + dst->__glibc_unused_qhook = to_ptrv(src->RES_STATE_QHOOK); + dst->__glibc_unused_rhook = to_ptrv(src->RES_STATE_RHOOK); dst->res_h_errno = src->res_h_errno; dst->_vcsock = src->_vcsock; dst->_flags = src->_flags; @@ -619,8 +619,8 @@ void* convert_res_state_to_64(void* d, void* s) dst->_flags = src->_flags; dst->_vcsock = src->_vcsock; dst->res_h_errno = src->res_h_errno; - dst->__glibc_unused_rhook = from_ptrv(src->__glibc_unused_rhook); - dst->__glibc_unused_qhook = from_ptrv(src->__glibc_unused_qhook); + dst->RES_STATE_RHOOK = from_ptrv(src->__glibc_unused_rhook); + dst->RES_STATE_QHOOK = from_ptrv(src->__glibc_unused_qhook); memmove(dst->sort_list, src->sort_list, sizeof(dst->sort_list)); dst->unused = src->unused; dst->ipv6_unavail = src->ipv6_unavail; From a2456b70dff1b5497416f5671d739fc65f1752bd Mon Sep 17 00:00:00 2001 From: Pepper Gray Date: Mon, 19 Oct 2026 20:42:47 +0200 Subject: [PATCH 14/20] conditional: RTLD_DL_SYMENT/LINKMAP Signed-off-by: Pepper Gray --- src/include/mydlfcn.h | 14 ++++++++++++++ src/wrapped/wrappedlibdl.c | 9 +-------- src/wrapped32/wrappedlibdl.c | 9 +-------- 3 files changed, 16 insertions(+), 16 deletions(-) create mode 100644 src/include/mydlfcn.h diff --git a/src/include/mydlfcn.h b/src/include/mydlfcn.h new file mode 100644 index 0000000000..cd743dd043 --- /dev/null +++ b/src/include/mydlfcn.h @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: MIT +#ifndef __MYDLFCN_H_ +#define __MYDLFCN_H_ + +#include + +#ifndef RTLD_DL_SYMENT +#define RTLD_DL_SYMENT 1 +#endif +#ifndef RTLD_DL_LINKMAP +#define RTLD_DL_LINKMAP 2 +#endif + +#endif // __MYDLFCN_H_ \ No newline at end of file diff --git a/src/wrapped/wrappedlibdl.c b/src/wrapped/wrappedlibdl.c index 38cfc2b58f..b8a4e5c968 100644 --- a/src/wrapped/wrappedlibdl.c +++ b/src/wrapped/wrappedlibdl.c @@ -19,6 +19,7 @@ #include "x64tls.h" #include "elfloader.h" #include "elfs/elfloader_private.h" +#include "mydlfcn.h" typedef struct dllib_s { library_t* lib; @@ -523,14 +524,6 @@ int my_dlclose(x64emu_t* emu, void *handle) unlockLibLoader(); return ret; } -#ifdef ANDROID -#ifndef RTLD_DL_SYMENT -#define RTLD_DL_SYMENT 1 -#endif -#ifndef RTLD_DL_LINKMAP -#define RTLD_DL_LINKMAP 2 -#endif -#endif static int my_dladdr1_internal(x64emu_t* emu, void *addr, void *i, void** extra_info, int flags) { diff --git a/src/wrapped32/wrappedlibdl.c b/src/wrapped32/wrappedlibdl.c index 379f588fc9..f65ea28495 100755 --- a/src/wrapped32/wrappedlibdl.c +++ b/src/wrapped32/wrappedlibdl.c @@ -19,7 +19,7 @@ #include "elfloader.h" #include "elfs/elfloader_private.h" #include "x64emu.h" - +#include "mydlfcn.h" #define LIBNAME libdl #ifdef ANDROID @@ -38,13 +38,6 @@ int my32_dladdr1(x64emu_t* emu, void *addr, void *info, void** extra_info, int f void* my_dlvsym(x64emu_t* emu, void *handle, void *symbol, const char *vername) EXPORT; int my32_dlinfo(x64emu_t* emu, void* handle, int request, void* info) EXPORT; -#ifndef RTLD_DL_SYMENT -#define RTLD_DL_SYMENT 1 -#endif -#ifndef RTLD_DL_LINKMAP -#define RTLD_DL_LINKMAP 2 -#endif - void dl_clear_error(); #define CLEARERR dl_clear_error() void dl_set_error(const char*); From c0022abbec62c0d4c094c8208532d29d8645b69e Mon Sep 17 00:00:00 2001 From: Pepper Gray Date: Mon, 19 Oct 2026 21:22:44 +0200 Subject: [PATCH 15/20] conditional: scandirat Signed-off-by: Pepper Gray --- CMakeLists.txt | 1 + src/include/libc_dirent.h | 10 +++++++ src/libtools/libc.c | 62 ++++++++++++++++++++++++++++++++++++++- src/wrapped/wrappedlibc.c | 1 + 4 files changed, 73 insertions(+), 1 deletion(-) create mode 100644 src/include/libc_dirent.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 557ec72a10..c67ea38066 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -458,6 +458,7 @@ set(PROJECT_SYMBOL_CHECKS obstack_vprintf stdio.h getprotobyname_r netdb.h getprotobynumber_r netdb.h + scandirat dirent.h ) list(LENGTH PROJECT_SYMBOL_CHECKS checks_len) diff --git a/src/include/libc_dirent.h b/src/include/libc_dirent.h new file mode 100644 index 0000000000..807f3b68a9 --- /dev/null +++ b/src/include/libc_dirent.h @@ -0,0 +1,10 @@ +// SPDX-License-Identifier: MIT +#ifndef _BOX64_LIBC_DIRENT_H_ +#define _BOX64_LIBC_DIRENT_H_ + +#ifndef HAVE_SCANDIRAT +int scandirat(int dirfd, const char *dirp, struct dirent ***namelist, + int (*filter)(const struct dirent *),int (*compar)(const struct dirent**, const struct dirent **)); +#endif + +#endif \ No newline at end of file diff --git a/src/libtools/libc.c b/src/libtools/libc.c index daa46eaec0..071ccd3bec 100644 --- a/src/libtools/libc.c +++ b/src/libtools/libc.c @@ -8,6 +8,11 @@ #include #include #include +#include +#include +#include +#include +#include #if !defined(HAVE_OBSTACK_VPRINTF) && !defined(ANDROID) @@ -45,7 +50,7 @@ int obstack_vprintf(struct obstack *obstack, const char *fmt, va_list args) if(len > 0) obstack_grow(obstack, buf, len); if(buf != buffer) free(buf); - return len; + return len; } #endif @@ -126,3 +131,58 @@ int getprotobynumber_r(int proto, struct protoent *result_buf, char *buf, size_t } #endif #endif + + +#ifndef HAVE_SCANDIRAT + +// Copyright (c) 2015-2016 Nuxi, https://nuxi.nl/ +// SPDX-License-Identifier: BSD-2-Clause +// https://github.com/WebAssembly/wasi-libc/blob/main/libc-bottom-half/cloudlibc/src/libc/dirent/scandirat.c +int scandirat(int dirfd, const char *dir, struct dirent ***res, + int (*sel)(const struct dirent *), + int (*cmp)(const struct dirent **, const struct dirent **)) +{ + dirfd = openat(dirfd, dir, O_RDONLY | O_DIRECTORY | O_CLOEXEC); + if (dirfd < 0) { + return -1; + } + + DIR *d = fdopendir(dirfd); + struct dirent *de, **names=0, **tmp; + size_t cnt=0, len=0; + int old_errno = errno; + + if (!d) { + close(dirfd); + return -1; + } + + while ((errno=0), (de = readdir(d))) { + if (sel && !sel(de)) continue; + if (cnt >= len) { + len = 2*len+1; + if (len > SIZE_MAX/sizeof *names) break; + tmp = realloc(names, len * sizeof *names); + if (!tmp) break; + names = tmp; + } + size_t size = de->d_reclen; + names[cnt] = malloc(size); + if (!names[cnt]) break; + memcpy(names[cnt++], de, size); + } + + closedir(d); + + if (errno) { + if (names) while (cnt-->0) free(names[cnt]); + free(names); + return -1; + } + errno = old_errno; + + if (cmp) qsort(names, cnt, sizeof *names, (int (*)(const void *, const void *))cmp); + *res = names; + return cnt; +} +#endif diff --git a/src/wrapped/wrappedlibc.c b/src/wrapped/wrappedlibc.c index 25c80c381a..3053adf5c5 100644 --- a/src/wrapped/wrappedlibc.c +++ b/src/wrapped/wrappedlibc.c @@ -100,6 +100,7 @@ extern const char *const sys_siglist[] __asm__("__sys_siglist"); #include "cpumask.h" #include "x64tls.h" #include "libc_malloc.h" +#include "libc_dirent.h" #ifndef LOG_INFO #define LOG_INFO 1 #endif From 67ac3c47fdf466b37ff81f74720dd2894c40a793 Mon Sep 17 00:00:00 2001 From: Pepper Gray Date: Mon, 19 Oct 2026 21:48:49 +0200 Subject: [PATCH 16/20] conditional: __ctype_b/tolower/toupper_loc Signed-off-by: Pepper Gray --- CMakeLists.txt | 13 +++++++++++++ src/include/libc_ctype.h | 14 ++++++++++++++ src/wrapped/wrappedlibc.c | 1 + src/wrapped32/wrappedlibc.c | 1 + 4 files changed, 29 insertions(+) create mode 100644 src/include/libc_ctype.h diff --git a/CMakeLists.txt b/CMakeLists.txt index c67ea38066..910aac4f64 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -530,6 +530,19 @@ elseif(NOT ANDROID) message(FATAL_ERROR "Unknown res_state layout!") endif() +check_c_source_compiles("#include +int main(void){ return &__ctype_b_loc == 0; }" CTYPE_B_LOC) +check_c_source_compiles("#include +extern const unsigned short int **__ctype_b_loc(void); +int main(void){ __ctype_b_loc(); return 0; }" CTYPE_B_LOC_EXT) + +if(CTYPE_B_LOC) # glibc + add_compile_definitions("HAVE_CTYPE_B_LOC") +elseif(CTYPE_B_LOC_EXT) # musl + add_compile_definitions("HAVE_CTYPE_B_LOC") + add_compile_definitions("HAVE_CTYPE_B_LOC_EXT") +endif() + # generated files set_source_files_properties( "${BOX64_ROOT}/src/git_head.h" diff --git a/src/include/libc_ctype.h b/src/include/libc_ctype.h new file mode 100644 index 0000000000..2563ee0504 --- /dev/null +++ b/src/include/libc_ctype.h @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: MIT +#ifndef _BOX64_LIBC_CTYPE_H_ +#define _BOX64_LIBC_CTYPE_H_ + +#ifdef HAVE_CTYPE_B_LOC_EXT + +#include + +const unsigned short **__ctype_b_loc(void); +const int32_t **__ctype_tolower_loc(void); +const int32_t **__ctype_toupper_loc(void); +#endif + +#endif \ No newline at end of file diff --git a/src/wrapped/wrappedlibc.c b/src/wrapped/wrappedlibc.c index 3053adf5c5..9bb7987068 100644 --- a/src/wrapped/wrappedlibc.c +++ b/src/wrapped/wrappedlibc.c @@ -101,6 +101,7 @@ extern const char *const sys_siglist[] __asm__("__sys_siglist"); #include "x64tls.h" #include "libc_malloc.h" #include "libc_dirent.h" +#include "libc_ctype.h" #ifndef LOG_INFO #define LOG_INFO 1 #endif diff --git a/src/wrapped32/wrappedlibc.c b/src/wrapped32/wrappedlibc.c index 7a36f700c7..a89837012c 100755 --- a/src/wrapped32/wrappedlibc.c +++ b/src/wrapped32/wrappedlibc.c @@ -79,6 +79,7 @@ #include "syscall_user_dispatch.h" #include "cpumask.h" #include "libc_malloc.h" +#include "libc_ctype.h" // need to undef all read / read64 stuffs! #undef pread From 3e4b4f85cb6df9353a851a4735db24a94866f1b4 Mon Sep 17 00:00:00 2001 From: Pepper Gray Date: Mon, 19 Oct 2026 21:56:34 +0200 Subject: [PATCH 17/20] conditional: glob_t Signed-off-by: Pepper Gray --- CMakeLists.txt | 23 +++++++++++++++++++++++ src/include/libc_glob.h | 13 +++++++++++++ src/wrapped32/wrappedlibc.c | 17 ++++++++++++++--- 3 files changed, 50 insertions(+), 3 deletions(-) create mode 100644 src/include/libc_glob.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 910aac4f64..8d898c1fca 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -543,6 +543,29 @@ elseif(CTYPE_B_LOC_EXT) # musl add_compile_definitions("HAVE_CTYPE_B_LOC_EXT") endif() +check_c_source_compiles("#include +int main(void){ glob_t g = { .gl_flags = 0 }; return 0; }" GLOB_T_GL_FLAGS) +check_c_source_compiles("#include +int main(void){ glob_t g = { .__dummy1 = 0 }; return 0; }" GLOB_T_DUMMY) + +if(GLOB_T_GL_FLAGS) # glibc + add_compile_definitions("GLOB_T_GL_FLAGS=gl_flags") + add_compile_definitions("GLOB_T_GL_CLOSEDIR=gl_closedir") + add_compile_definitions("GLOB_T_GL_READDIR=gl_readdir") + add_compile_definitions("GLOB_T_GL_OPENDIR=gl_opendir") + add_compile_definitions("GLOB_T_GL_LSTAT=gl_lstat") + add_compile_definitions("GLOB_T_GL_STAT=gl_stat") +elseif(GLOB_T_DUMMY) # musl + add_compile_definitions("GLOB_T_GL_FLAGS=__dummy1") + add_compile_definitions("GLOB_T_GL_CLOSEDIR=__dummy2[0]") + add_compile_definitions("GLOB_T_GL_READDIR=__dummy2[1]") + add_compile_definitions("GLOB_T_GL_OPENDIR=__dummy2[2]") + add_compile_definitions("GLOB_T_GL_LSTAT=__dummy2[3]") + add_compile_definitions("GLOB_T_GL_STAT=__dummy2[4]") +elseif(NOT ANDROID) + message(FATAL_ERROR "Unknown glob_t layout!") +endif() + # generated files set_source_files_properties( "${BOX64_ROOT}/src/git_head.h" diff --git a/src/include/libc_glob.h b/src/include/libc_glob.h new file mode 100644 index 0000000000..d3f7430d07 --- /dev/null +++ b/src/include/libc_glob.h @@ -0,0 +1,13 @@ +// SPDX-License-Identifier: MIT +#ifndef _BOX64_LIBC_GLOB_H_ +#define _BOX64_LIBC_GLOB_H_ + +#ifndef GLOB_APPEND +#define GLOB_APPEND (1 << 5) +#endif + +#ifndef GLOB_ALTDIRFUNC +# define GLOB_ALTDIRFUNC (1 << 9) +#endif + +#endif \ No newline at end of file diff --git a/src/wrapped32/wrappedlibc.c b/src/wrapped32/wrappedlibc.c index a89837012c..82d92a6ee9 100755 --- a/src/wrapped32/wrappedlibc.c +++ b/src/wrapped32/wrappedlibc.c @@ -80,6 +80,7 @@ #include "cpumask.h" #include "libc_malloc.h" #include "libc_ctype.h" +#include "libc_glob.h" // need to undef all read / read64 stuffs! #undef pread @@ -1751,7 +1752,7 @@ typedef struct my_glob_32_s ulong_t gl_offs; int gl_flags; ptr_t gl_closedir; //void (*gl_closedir) (void *); - ptr_t gl_readir; //struct dirent *(*gl_readdir) (void *); + ptr_t gl_readdir; //struct dirent *(*gl_readdir) (void *); ptr_t gl_opendir; //void *(*gl_opendir) (const char *); ptr_t gl_lstat; //int (*gl_lstat) (const char *__restrict, struct stat *__restrict); ptr_t gl_stat; //int (*gl_stat) (const char *__restrict, struct stat *__restrict); @@ -1768,8 +1769,13 @@ static void convert_glob_to_32(void* d, void* s, int is64) dst->gl_pathc = to_ulong(src->gl_pathc); dst->gl_pathv = to_ptrv(src->gl_pathv); dst->gl_offs = to_ulong(src->gl_offs); - dst->gl_flags = src->gl_flags; + dst->gl_flags = src->GLOB_T_GL_FLAGS; // TODO: functions pointers + // dst->gl_closedir = to_ptrv(src->GLOB_T_GL_CLOSEDIR); + // dst->gl_readdir = to_ptrv(src->GLOB_T_GL_READDIR); + // dst->gl_opendir = to_ptrv(src->GLOB_T_GL_OPENDIR); + // dst->gl_lstat = to_ptrv(src->GLOB_T_GL_LSTAT); + // dst->gl_stat = to_ptrv(src->GLOB_T_GL_STAT); } static void convert_glob_to_64(void* d, void* s, int is64) { @@ -1779,10 +1785,15 @@ static void convert_glob_to_64(void* d, void* s, int is64) dst->gl_pathc = from_ulong(src->gl_pathc); dst->gl_pathv = from_ptrv(src->gl_pathv); dst->gl_offs = from_ulong(src->gl_offs); - dst->gl_flags = src->gl_flags; + dst->GLOB_T_GL_FLAGS = src->gl_flags; for(ulong_t i=dst->gl_pathc; i--;) dst->gl_pathv[i] = from_ptrv(((ptr_t*)dst->gl_pathv)[i]); // TODO: functions pointers + // dst->GLOB_T_GL_CLOSEDIR = from_ptrv(src->gl_closedir); + // dst->GLOB_T_GL_READDIR = from_ptrv(src->gl_readdir); + // dst->GLOB_T_GL_OPENDIR = from_ptrv(src->gl_opendir); + // dst->GLOB_T_GL_LSTAT = from_ptrv(src->gl_lstat); + // dst->GLOB_T_GL_STAT = from_ptrv(src->gl_stat); } EXPORT int32_t my32_glob(x64emu_t *emu, void* pat, int32_t flags, void* errfnc, void* pglob) From 3e93ba08cd1a886c815e6e11f9c27291d04d0413 Mon Sep 17 00:00:00 2001 From: Pepper Gray Date: Mon, 19 Oct 2026 21:58:39 +0200 Subject: [PATCH 18/20] conditional: posix_spawn_file_actions_t Signed-off-by: Pepper Gray --- CMakeLists.txt | 21 +++++++++++++++++++++ src/wrapped32/wrappedlibc.c | 12 ++++++------ 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8d898c1fca..74ca02898f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -566,6 +566,27 @@ elseif(NOT ANDROID) message(FATAL_ERROR "Unknown glob_t layout!") endif() +check_c_source_compiles("#include +int main(void){ posix_spawn_file_actions_t a = { .__allocated = 0 }; return 0; }" + POSIX_SPAWN_FILE_ACTIONS_T__ALLOCATED) +check_c_source_compiles("#include +int main(void){ posix_spawn_file_actions_t a = { .__pad0 = {0} }; return 0; }" + POSIX_SPAWN_FILE_ACTIONS_T__PAD0) + +if(POSIX_SPAWN_FILE_ACTIONS_T__ALLOCATED) # glibc + add_compile_definitions("POSIX_SPAWN_FILE_ACTIONS_T__ALLOCATED=__allocated") + add_compile_definitions("POSIX_SPAWN_FILE_ACTIONS_T__USED=__used") + add_compile_definitions("POSIX_SPAWN_FILE_ACTIONS_T__ACTIONS=__actions") + add_compile_definitions("POSIX_SPAWN_FILE_ACTIONS_T__PAD=__pad") +elseif(POSIX_SPAWN_FILE_ACTIONS_T__PAD0) # musl + add_compile_definitions("POSIX_SPAWN_FILE_ACTIONS_T__ALLOCATED=__pad0[0]") + add_compile_definitions("POSIX_SPAWN_FILE_ACTIONS_T__USED=__pad0[1]") + add_compile_definitions("POSIX_SPAWN_FILE_ACTIONS_T__ACTIONS=__actions") + add_compile_definitions("POSIX_SPAWN_FILE_ACTIONS_T__PAD=__pad") +elseif(NOT ANDROID) + message(FATAL_ERROR "Unknown posix_spawn_file_actions_t layout!") +endif() + # generated files set_source_files_properties( "${BOX64_ROOT}/src/git_head.h" diff --git a/src/wrapped32/wrappedlibc.c b/src/wrapped32/wrappedlibc.c index 82d92a6ee9..1d8f40d0b4 100755 --- a/src/wrapped32/wrappedlibc.c +++ b/src/wrapped32/wrappedlibc.c @@ -2208,17 +2208,17 @@ void convert_file_action_to_32(void* d, void* s) { posix_spawn_file_actions_32_t* dst = d; posix_spawn_file_actions_t* src = s; - dst->__allocated = src->__allocated; - dst->__used = src->__used; - dst->__actions = to_ptrv(src->__actions); + dst->__allocated = src->POSIX_SPAWN_FILE_ACTIONS_T__ALLOCATED; + dst->__used = src->POSIX_SPAWN_FILE_ACTIONS_T__USED; + dst->__actions = to_ptrv(src->POSIX_SPAWN_FILE_ACTIONS_T__ACTIONS); } void convert_file_action_to_64(void* d, void* s) { posix_spawn_file_actions_t* dst = d; posix_spawn_file_actions_32_t* src = s; - dst->__actions = from_ptrv(src->__actions); - dst->__used = src->__used; - dst->__allocated = src->__allocated; + dst->POSIX_SPAWN_FILE_ACTIONS_T__ACTIONS = from_ptrv(src->__actions); + dst->POSIX_SPAWN_FILE_ACTIONS_T__USED = src->__used; + dst->POSIX_SPAWN_FILE_ACTIONS_T__ALLOCATED = src->__allocated; } EXPORT int my32_posix_spawn_file_actions_init(x64emu_t* emu, posix_spawn_file_actions_32_t* action) From 0d09038d7ffdeef36ca02a109df7063bd8fe26e7 Mon Sep 17 00:00:00 2001 From: Pepper Gray Date: Mon, 19 Oct 2026 22:00:20 +0200 Subject: [PATCH 19/20] conditional: __NFDBITS Signed-off-by: Pepper Gray --- src/include/libc_select.h | 13 +++++++++++++ src/wrapped32/wrappedlibc.c | 1 + 2 files changed, 14 insertions(+) create mode 100644 src/include/libc_select.h diff --git a/src/include/libc_select.h b/src/include/libc_select.h new file mode 100644 index 0000000000..629a656e77 --- /dev/null +++ b/src/include/libc_select.h @@ -0,0 +1,13 @@ +// SPDX-License-Identifier: MIT +#ifndef _BOX64_LIBC_SELECT_H_ +#define _BOX64_LIBC_SELECT_H_ + +#ifndef __NFDBITS +#ifdef NFDBITS +#define __NFDBITS NFDBITS +#else +#error NFDBITS not defined by libc +#endif +#endif + +#endif \ No newline at end of file diff --git a/src/wrapped32/wrappedlibc.c b/src/wrapped32/wrappedlibc.c index 1d8f40d0b4..f81ec95bb1 100755 --- a/src/wrapped32/wrappedlibc.c +++ b/src/wrapped32/wrappedlibc.c @@ -81,6 +81,7 @@ #include "libc_malloc.h" #include "libc_ctype.h" #include "libc_glob.h" +#include "libc_select.h" // need to undef all read / read64 stuffs! #undef pread From e9d0d5c66f5af707eaaf5cb29e40333e923b9219 Mon Sep 17 00:00:00 2001 From: Pepper Gray Date: Mon, 19 Oct 2026 22:52:12 +0200 Subject: [PATCH 20/20] conditional: __chk_fail Signed-off-by: Pepper Gray --- CMakeLists.txt | 19 +++++++++++++++++++ src/wrapped32/wrappedlibc.c | 7 ++++++- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 74ca02898f..2f1f42133b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -483,6 +483,25 @@ foreach(i RANGE 0 ${checks_last} 2) endif() endforeach() +include(CheckFunctionExists) + +set(PROJECT_FUNCTION_CHECKS + __chk_fail +) + +foreach(function IN LISTS PROJECT_FUNCTION_CHECKS) + string(MAKE_C_IDENTIFIER "${function}" function_ident) + string(TOUPPER "${function_ident}" function_ident) + + set(var "HAVE_${function_ident}") + + check_function_exists("${function}" "${var}") + + if(${var}) + add_compile_definitions("${var}=1") + endif() +endforeach() + include(CheckCSourceCompiles) check_c_source_compiles("#include diff --git a/src/wrapped32/wrappedlibc.c b/src/wrapped32/wrappedlibc.c index f81ec95bb1..725207a01e 100755 --- a/src/wrapped32/wrappedlibc.c +++ b/src/wrapped32/wrappedlibc.c @@ -2377,8 +2377,13 @@ EXPORT int32_t my32___cxa_thread_atexit_impl(x64emu_t* emu, void* dtor, void* ob extern void __chk_fail(); EXPORT unsigned long int my32___fdelt_chk (unsigned long int d) { - if (d >= FD_SETSIZE) + if (d >= FD_SETSIZE) { +#ifdef HAVE___CHK_FAIL __chk_fail (); +#else + abort (); +#endif + } return d / __NFDBITS; }