diff --git a/CMakeLists.txt b/CMakeLists.txt index c74391b616..b101f4fe97 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,213 @@ add_custom_target(generate_dynacache_hashes VERBATIM ) +include(CheckIncludeFile) + +set(PROJECT_HEADERS + execinfo.h + error.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() + +include(CheckSymbolExists) + +set(PROJECT_SYMBOL_CHECKS + mallopt malloc.h + malloc_trim malloc.h + mallinfo malloc.h + 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 + dlvsym dlfcn.h + obstack_vprintf stdio.h + getprotobyname_r netdb.h + getprotobynumber_r netdb.h + scandirat dirent.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() + +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 +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() + +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() + +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() + +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() + +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() + +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() + +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" @@ -477,6 +685,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" @@ -1383,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 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/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/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/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/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/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/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/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/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/libc.c b/src/libtools/libc.c new file mode 100644 index 0000000000..071ccd3bec --- /dev/null +++ b/src/libtools/libc.c @@ -0,0 +1,188 @@ +// SPDX-License-Identifier: MIT +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#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 + +#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 + + +#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/libtools/libc_net32.c b/src/libtools/libc_net32.c index aac38a317a..60afaa9636 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) { @@ -598,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; @@ -618,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; 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); 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*); diff --git a/src/libtools/signal32.c b/src/libtools/signal32.c index cf16e276ea..c1e9c4ea20 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 @@ -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) { diff --git a/src/libtools/signals.c b/src/libtools/signals.c index 8d72716325..45639ebd4b 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 @@ -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) @@ -1806,7 +1808,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) { @@ -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 08317ed40c..724a0aacff 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; @@ -474,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; @@ -487,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; @@ -1089,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; @@ -1451,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); @@ -1461,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 c03e31585e..fa44f15af5 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; @@ -883,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) { @@ -904,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) { @@ -918,6 +925,7 @@ EXPORT int my32_pthread_attr_getaffinity_np(x64emu_t* emu, void* attr, uint32_t } return ret; } +#endif #endif @@ -1056,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; } @@ -1101,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); @@ -1109,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) 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) 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/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) { diff --git a/src/wrapped/wrappedlibc.c b/src/wrapped/wrappedlibc.c index 65f41f1596..9bb7987068 100644 --- a/src/wrapped/wrappedlibc.c +++ b/src/wrapped/wrappedlibc.c @@ -99,6 +99,9 @@ extern const char *const sys_siglist[] __asm__("__sys_siglist"); #include "random.h" #include "cpumask.h" #include "x64tls.h" +#include "libc_malloc.h" +#include "libc_dirent.h" +#include "libc_ctype.h" #ifndef LOG_INFO #define LOG_INFO 1 #endif @@ -4173,6 +4176,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 +4186,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 +4202,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/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/wrappedlibc.c b/src/wrapped32/wrappedlibc.c index 71653dd567..725207a01e 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,10 @@ #include "box32_inputevent.h" #include "syscall_user_dispatch.h" #include "cpumask.h" +#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 @@ -1748,7 +1753,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); @@ -1765,8 +1770,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) { @@ -1776,10 +1786,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) @@ -2194,17 +2209,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) @@ -2362,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; } @@ -2500,27 +2520,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; } 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*); 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)