From 1d349ca8781511f22b6094025398407064bca92d Mon Sep 17 00:00:00 2001 From: Pepper Gray Date: Mon, 19 Oct 2026 17:12:51 +0200 Subject: [PATCH 01/21] 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 c9647c2a48cd30139906629c6eceb2142a378bac Mon Sep 17 00:00:00 2001 From: Pepper Gray Date: Mon, 19 Oct 2026 17:21:01 +0200 Subject: [PATCH 02/21] 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 a57141ba54c04faa611e95bf160145980e135a84 Mon Sep 17 00:00:00 2001 From: Pepper Gray Date: Mon, 19 Oct 2026 18:22:24 +0200 Subject: [PATCH 03/21] 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 9284a654f4e5817c2d3da5dce276884935171c29 Mon Sep 17 00:00:00 2001 From: Pepper Gray Date: Mon, 19 Oct 2026 18:35:05 +0200 Subject: [PATCH 04/21] 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 0d7d1e6f483a212945a5b56b7b10bc3f35c8ea5a Mon Sep 17 00:00:00 2001 From: Pepper Gray Date: Mon, 19 Oct 2026 18:42:32 +0200 Subject: [PATCH 05/21] 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 a4f71342bdac82942a9bd40d95f24eb056a9d4cc Mon Sep 17 00:00:00 2001 From: Pepper Gray Date: Mon, 19 Oct 2026 18:55:48 +0200 Subject: [PATCH 06/21] 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 01be2c4d9a74df7040febe4a9f3f7cfd432ec2a7 Mon Sep 17 00:00:00 2001 From: Pepper Gray Date: Tue, 20 Oct 2026 04:29:20 +0200 Subject: [PATCH 07/21] 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 c251a2ac40c00c5a6f7d373ef20b323fb253a07b Mon Sep 17 00:00:00 2001 From: Pepper Gray Date: Mon, 19 Oct 2026 18:59:15 +0200 Subject: [PATCH 08/21] 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 412ca1ee60214c620e71510273a6cc37040c85ba Mon Sep 17 00:00:00 2001 From: Pepper Gray Date: Mon, 19 Oct 2026 19:07:23 +0200 Subject: [PATCH 09/21] 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 e8d50f95346d669d2123c4bb78860ddbd56502de Mon Sep 17 00:00:00 2001 From: Pepper Gray Date: Mon, 19 Oct 2026 19:45:56 +0200 Subject: [PATCH 10/21] 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 242a54a76565686ea09ba215a93f9f8ead5f4086 Mon Sep 17 00:00:00 2001 From: Pepper Gray Date: Mon, 19 Oct 2026 19:56:18 +0200 Subject: [PATCH 11/21] 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 fa5a50bff42ec1e51b46b4d84c855c838092bb8c Mon Sep 17 00:00:00 2001 From: Pepper Gray Date: Mon, 19 Oct 2026 20:34:49 +0200 Subject: [PATCH 12/21] 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 52baa2cf654ea05de71a840ad6809c7110b7ef79 Mon Sep 17 00:00:00 2001 From: Pepper Gray Date: Mon, 19 Oct 2026 20:36:48 +0200 Subject: [PATCH 13/21] 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 98ef4e038c039a70bb96d6da54af67d6dd5b91e5 Mon Sep 17 00:00:00 2001 From: Pepper Gray Date: Mon, 19 Oct 2026 20:42:47 +0200 Subject: [PATCH 14/21] 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 a3eb9f78014ec0b845ede49bbdc29cdcaf98be8e Mon Sep 17 00:00:00 2001 From: Pepper Gray Date: Mon, 19 Oct 2026 21:22:44 +0200 Subject: [PATCH 15/21] 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 79283b9dd3c309e7303353b3bb8c4bd80f74989c Mon Sep 17 00:00:00 2001 From: Pepper Gray Date: Mon, 19 Oct 2026 21:48:49 +0200 Subject: [PATCH 16/21] 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 711a01b5f3329e24e2a1665a92de36ba6154db98 Mon Sep 17 00:00:00 2001 From: Pepper Gray Date: Mon, 19 Oct 2026 21:56:34 +0200 Subject: [PATCH 17/21] 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 75113265c0e680080bf104cd02989495eb838d96 Mon Sep 17 00:00:00 2001 From: Pepper Gray Date: Mon, 19 Oct 2026 21:58:39 +0200 Subject: [PATCH 18/21] 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 1b7993b766f7eb5906a35d72784c0dfc32dc393e Mon Sep 17 00:00:00 2001 From: Pepper Gray Date: Mon, 19 Oct 2026 22:00:20 +0200 Subject: [PATCH 19/21] 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 4f2b1731eab5944d4673e41334e8a026a90acf59 Mon Sep 17 00:00:00 2001 From: Pepper Gray Date: Mon, 19 Oct 2026 22:52:12 +0200 Subject: [PATCH 20/21] 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; } From 08836024b81204b8c6d21582627b49495ca362ee Mon Sep 17 00:00:00 2001 From: Pepper Gray Date: Mon, 19 Oct 2026 22:21:32 +0200 Subject: [PATCH 21/21] musl: link additional libs Signed-off-by: Pepper Gray --- CMakeLists.txt | 70 +++++++++++++++++++++++++++++++++++++++++++++++++ docs/COMPILE.md | 13 +++++++++ 2 files changed, 83 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2f1f42133b..b101f4fe97 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -423,6 +423,7 @@ include(CheckIncludeFile) set(PROJECT_HEADERS execinfo.h + error.h ) foreach(header IN LISTS PROJECT_HEADERS) @@ -606,6 +607,25 @@ elseif(NOT ANDROID) message(FATAL_ERROR "Unknown posix_spawn_file_actions_t layout!") endif() +if(HAVE_ERROR_H) + set(ERROR_TEST [[ + #include + int main(void) { error(0, 0, "test"); return 0; } + ]]) + check_c_source_compiles("${ERROR_TEST}" HAVE_ERROR) + if(NOT HAVE_ERROR) + include(CMakePushCheckState) + cmake_push_check_state() + set(CMAKE_REQUIRED_LIBRARIES error) + check_c_source_compiles("${ERROR_TEST}" HAVE_ERROR_LIB) + cmake_pop_check_state() + endif() +endif() + +if(NOT HAVE_ERROR AND NOT HAVE_ERROR_LIB) + message(FATAL_ERROR "error() is unavailable") +endif() + # generated files set_source_files_properties( "${BOX64_ROOT}/src/git_head.h" @@ -1572,6 +1592,56 @@ if(NOT NOBOX64) endif() target_link_libraries(${BOX64} interpreter) + set(BOX64_MUSL FALSE) + + if(CMAKE_SYSTEM_NAME STREQUAL "Linux") + if(CMAKE_C_COMPILER_TARGET MATCHES "musl") + set(BOX64_MUSL TRUE) + set(BOX64_LIBC_TARGET "${CMAKE_C_COMPILER_TARGET}") + else() + execute_process( + COMMAND "${CMAKE_C_COMPILER}" -dumpmachine + OUTPUT_VARIABLE BOX64_CC_MACHINE + OUTPUT_STRIP_TRAILING_WHITESPACE + ERROR_QUIET + ) + + if(BOX64_CC_MACHINE MATCHES "musl") + set(BOX64_MUSL TRUE) + set(BOX64_LIBC_TARGET "${BOX64_CC_MACHINE}") + endif() + endif() + endif() + + if(BOX64_MUSL) + set(MUSL_COMPAT_LIBS + argp + obstack + fts + ucontext + ) + + if(HAVE_ERROR_LIB) + list(APPEND MUSL_COMPAT_LIBS error) + endif() + + foreach(lib IN LISTS MUSL_COMPAT_LIBS) + string(TOUPPER "${lib}" LIB_UPPER) + set(LIB_VAR "MUSL_${LIB_UPPER}_LIBRARY") + + message(STATUS "Looking for lib${lib}") + find_library(${LIB_VAR} NAMES ${lib}) + + if(${LIB_VAR}) + message(STATUS "Looking for lib${lib} - found: ${${LIB_VAR}}") + else() + message(FATAL_ERROR "Looking for lib${lib} - not found.") + endif() + + target_link_libraries(${BOX64} "${MUSL_${LIB_UPPER}_LIBRARY}") + endforeach() + endif() + if(${CMAKE_VERSION} VERSION_LESS "3.13") if(NOT NOLOADADDR) if(CMAKE_C_COMPILER_ID STREQUAL "Clang" OR WITH_MOLD) diff --git a/docs/COMPILE.md b/docs/COMPILE.md index b8d9b7afeb..fc0875fa9a 100644 --- a/docs/COMPILE.md +++ b/docs/COMPILE.md @@ -309,6 +309,19 @@ Add `-DWITH_MOLD=1` option when GNU ld is extremely slow. Then run `mold -run ma You can now build box64 statically linked, with `-DSTATICBUILD` to use inside of a x86_64 chroot. Note that this version of box64 will only have the minimal wrapped libs, such as libc, libm and libpthread. Other libs (like libGL or libvulkan, SDL2, etc...) will use x86_64 versions. A static build is intended to be used in a docker image, or in a headless server. It is highly experimental, but feedback is always welcome. + +#### Build with musl + +Building with musl needs additional libraries: + +| Library | Alpine Linux | Gentoo | +| -------- | ------------------- | ----------------------------- | +| argp | `argp-standalone` | `sys-libs/argp-standalone` | +| obstack | `musl-obstack` | `sys-libs/obstack-standalone` | +| fts | `musl-fts` | `sys-libs/fts-standalone` | +| ucontext | `libucontext` | `sys-libs/libucontext` | +| error | `musl-legacy-error` | `sys-libs/error-standalone` | + ---- ## Testing