From e4b823b197bb0f8270d2b8fb1fdb0e3bab070e4d Mon Sep 17 00:00:00 2001 From: Yang Liu Date: Wed, 28 May 2025 20:03:56 +0800 Subject: [PATCH] [WOW64] Supported logging to stdout --- src/build_info.c | 2 +- src/core.c | 42 ++++---------------------- src/dynarec/arm64/dynarec_arm64_00.c | 4 +-- src/include/debug.h | 43 ++++++++++----------------- src/include/env.h | 2 +- src/include/os.h | 3 ++ src/os/os_linux.c | 44 ++++++++++++++++++++++++++-- src/os/os_wine.c | 25 ++++++++++++++++ wow64/CMakeLists.txt | 1 + wow64/crt.c | 15 ++++++++++ wow64/wowbox64.c | 5 +++- 11 files changed, 115 insertions(+), 71 deletions(-) diff --git a/src/build_info.c b/src/build_info.c index 612a8871ad..964bb9d93b 100644 --- a/src/build_info.c +++ b/src/build_info.c @@ -17,7 +17,7 @@ void PrintBox64Version(int prefix) { - printf_ftrace(prefix, BOX64_BUILD_INFO_STRING WITH_DYNAREC_STR WITH_TRACE_STR " built on %s %s\n", + PrintfFtrace(prefix, BOX64_BUILD_INFO_STRING WITH_DYNAREC_STR WITH_TRACE_STR " built on %s %s\n", __DATE__, __TIME__); } diff --git a/src/core.c b/src/core.c index 88cdc6253a..5e164c7a27 100644 --- a/src/core.c +++ b/src/core.c @@ -194,36 +194,6 @@ void openFTrace(int reopen) } } -static void check_ftrace() -{ - int fd = fileno(ftrace); - if(fd<0 || lseek(fd, 0, SEEK_CUR)==(off_t)-1) { - ftrace=fopen(ftrace_name, "a"); - printf_log(LOG_INFO, "%04d|Recreated trace because fd was invalid\n", GetTID()); - } -} -void printf_ftrace(int prefix, const char* fmt, ...) -{ - if(ftrace_name) { - check_ftrace(); - } - - static const char* names[2] = {"BOX64", "BOX32"}; - - if (prefix && ftrace == stdout) { - if (prefix > 1) { - fprintf(ftrace, "[\033[31m%s\033[0m] ", names[box64_is32bits]); - } else { - fprintf(ftrace, "[%s] ", names[box64_is32bits]); - } - } - va_list args; - va_start(args, fmt); - vfprintf(ftrace, fmt, args); - fflush(ftrace); - va_end(args); -} - void my_prepare_fork() { if (ftrace_has_pid && ftrace && (ftrace != stdout) && (ftrace != stderr)) { @@ -575,12 +545,12 @@ void AddNewLibs(const char* list) } void PrintHelp() { - printf_ftrace(0, "This is Box64, the Linux x86_64 emulator with a twist.\n"); - printf_ftrace(0, "Usage is 'box64 [options] path/to/software [args]' to launch x86_64 software.\n"); - printf_ftrace(0, " options are:\n"); - printf_ftrace(0, " '-v'|'--version' to print box64 version and quit\n"); - printf_ftrace(0, " '-h'|'--help' to print this and quit\n"); - printf_ftrace(0, " '-k'|'--kill-all' to kill all box64 instances\n"); + PrintfFtrace(0, "This is Box64, the Linux x86_64 emulator with a twist.\n"); + PrintfFtrace(0, "Usage is 'box64 [options] path/to/software [args]' to launch x86_64 software.\n"); + PrintfFtrace(0, " options are:\n"); + PrintfFtrace(0, " '-v'|'--version' to print box64 version and quit\n"); + PrintfFtrace(0, " '-h'|'--help' to print this and quit\n"); + PrintfFtrace(0, " '-k'|'--kill-all' to kill all box64 instances\n"); } void KillAllInstances() diff --git a/src/dynarec/arm64/dynarec_arm64_00.c b/src/dynarec/arm64/dynarec_arm64_00.c index 856b107bed..59a4c5e335 100644 --- a/src/dynarec/arm64/dynarec_arm64_00.c +++ b/src/dynarec/arm64/dynarec_arm64_00.c @@ -2591,7 +2591,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin *ok = 0; *need_epilog = 1; } else { - MESSAGE(LOG_DUMP, "Native Call to %s\n", getBridgeName((void*)ip)?:GetNativeName(GetNativeFnc(ip))); + MESSAGE(LOG_DUMP, "Native Call to %s\n", GetBridgeName((void*)ip) ?: GetNativeName(GetNativeFnc(ip))); x87_stackcount(dyn, ninst, x1); x87_forget(dyn, ninst, x3, x4, 0); sse_purge07cache(dyn, ninst, x3); @@ -3374,7 +3374,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin MOV64x(x2, addr); } PUSH1(x2); - MESSAGE(LOG_DUMP, "Native Call to %s (retn=%d)\n", getBridgeName((void*)(dyn->insts[ninst].natcall-1))?:GetNativeName(GetNativeFnc(dyn->insts[ninst].natcall-1)), dyn->insts[ninst].retn); + MESSAGE(LOG_DUMP, "Native Call to %s (retn=%d)\n", GetBridgeName((void*)(dyn->insts[ninst].natcall - 1)) ?: GetNativeName(GetNativeFnc(dyn->insts[ninst].natcall - 1)), dyn->insts[ninst].retn); SKIPTEST(x1); // disable test as this hack dos 2 instructions for 1 // calling a native function SMEND(); diff --git a/src/include/debug.h b/src/include/debug.h index 92425ad176..abd94bf7cd 100644 --- a/src/include/debug.h +++ b/src/include/debug.h @@ -70,55 +70,42 @@ extern int box64_tcmalloc_minimal; // when using tcmalloc_minimal #define LOG_NEVER 3 #define LOG_VERBOSE 3 -#ifndef _WIN32 // TODO: better wow64 support? -void printf_ftrace(int prefix, const char* fmt, ...); -#define printf_log_prefix(prefix, L, ...) \ - do { \ - if ((L) <= BOX64ENV(log)) { printf_ftrace(prefix + (prefix && (L) == LOG_NONE), __VA_ARGS__); } \ +#define printf_log_prefix(prefix, L, ...) \ + do { \ + if ((L) <= BOX64ENV(log)) { PrintfFtrace(prefix + (prefix && (L) == LOG_NONE), __VA_ARGS__); } \ } while (0) #define printf_log(L, ...) printf_log_prefix(1, L, __VA_ARGS__) -#define printf_dump_prefix(prefix, L, ...) \ - do { \ - if (BOX64ENV(dump) || ((L) <= BOX64ENV(log))) { printf_ftrace(prefix, __VA_ARGS__); } \ +#define printf_dump_prefix(prefix, L, ...) \ + do { \ + if (BOX64ENV(dump) || ((L) <= BOX64ENV(log))) { PrintfFtrace(prefix, __VA_ARGS__); } \ } while (0) #define printf_dump(L, ...) printf_dump_prefix(1, L, __VA_ARGS__) -#define printf_dlsym_prefix(prefix, L, ...) \ - do { \ - if (BOX64ENV(dlsym_error) || BOX64ENV(dump) || ((L) <= BOX64ENV(log))) { printf_ftrace(prefix, __VA_ARGS__); } \ +#define printf_dlsym_prefix(prefix, L, ...) \ + do { \ + if (BOX64ENV(dlsym_error) || BOX64ENV(dump) || ((L) <= BOX64ENV(log))) { PrintfFtrace(prefix, __VA_ARGS__); } \ } while (0) #define printf_dlsym_dump(L, ...) printf_dlsym_dump_prefix(1, L, __VA_ARGS__) -#define printf_dlsym_dump_prefix(prefix, L, ...) \ - do { \ - if (BOX64ENV(dlsym_error) || ((L) <= BOX64ENV(log))) { printf_ftrace(prefix, __VA_ARGS__); } \ +#define printf_dlsym_dump_prefix(prefix, L, ...) \ + do { \ + if (BOX64ENV(dlsym_error) || ((L) <= BOX64ENV(log))) { PrintfFtrace(prefix, __VA_ARGS__); } \ } while (0) #define printf_dlsym(L, ...) printf_dlsym_prefix(1, L, __VA_ARGS__) -#define dynarec_log_prefix(prefix, L, ...) \ - do { \ - if ((L) <= BOX64ENV(dynarec_log)) { printf_ftrace(prefix, __VA_ARGS__); } \ +#define dynarec_log_prefix(prefix, L, ...) \ + do { \ + if ((L) <= BOX64ENV(dynarec_log)) { PrintfFtrace(prefix, __VA_ARGS__); } \ } while (0) #define dynarec_log(L, ...) dynarec_log_prefix(1, L, __VA_ARGS__) -#else -#define printf_log_prefix(prefix, L, ...) -#define printf_log(L, ...) -#define printf_dump_prefix(prefix, L, ...) -#define printf_dump(L, ...) -#define printf_dlsym_prefix(prefix, L, ...) -#define printf_dlsym(L, ...) -#define dynarec_log_prefix(prefix, L, ...) -#define dynarec_log(L, ...) -#endif - #define EXPORT __attribute__((visibility("default"))) #ifdef BUILD_DYNAMIC diff --git a/src/include/env.h b/src/include/env.h index f3456647d2..db4974bd29 100644 --- a/src/include/env.h +++ b/src/include/env.h @@ -23,7 +23,7 @@ #ifdef _WIN32 #define DEFAULT_LOG_LEVEL (LOG_INFO) -#define BOX64_NOBANNER_DEFAULT (1) +#define BOX64_NOBANNER_DEFAULT (0) #else extern char* ftrace_name; #define DEFAULT_LOG_LEVEL (ftrace_name ? LOG_INFO : (isatty(fileno(stdout)) ? LOG_INFO : LOG_NONE)) diff --git a/src/include/os.h b/src/include/os.h index f141e99e92..03c075e7eb 100644 --- a/src/include/os.h +++ b/src/include/os.h @@ -56,6 +56,7 @@ void PersonalityAddrLimit32Bit(void); int IsAddrElfOrFileMapped(uintptr_t addr); const char* GetNativeName(void* p); +const char* GetBridgeName(void* p); // ---------------------------------------------------------------- #ifndef _WIN32 @@ -96,4 +97,6 @@ extern int isnanf(float); #define isinff isinf #endif +void PrintfFtrace(int prefix, const char* fmt, ...); + #endif //__OS_H_ diff --git a/src/os/os_linux.c b/src/os/os_linux.c index 556d4d9b7c..a8258db64b 100644 --- a/src/os/os_linux.c +++ b/src/os/os_linux.c @@ -6,6 +6,7 @@ #include #include #include +#include #include "os.h" #include "signals.h" @@ -89,11 +90,16 @@ void* GetSegmentBase(uint32_t desc) return ptr; } +const char* GetBridgeName(void* p) +{ + return getBridgeName(p); +} + const char* GetNativeName(void* p) { static char buff[500] = { 0 }; { - const char* n = getBridgeName(p); + const char* n = GetBridgeName(p); if (n) return n; } @@ -161,4 +167,38 @@ int InternalMunmap(void* addr, unsigned long length) int ret = libc_munmap(addr, length); #endif return ret; -} \ No newline at end of file +} + +extern FILE* ftrace; +extern char* ftrace_name; + +static void checkFtrace() +{ + int fd = fileno(ftrace); + if (fd < 0 || lseek(fd, 0, SEEK_CUR) == (off_t)-1) { + ftrace = fopen(ftrace_name, "a"); + printf_log(LOG_INFO, "%04d|Recreated trace because fd was invalid\n", GetTID()); + } +} + +void PrintfFtrace(int prefix, const char* fmt, ...) +{ + if (ftrace_name) { + checkFtrace(); + } + + static const char* names[2] = { "BOX64", "BOX32" }; + + if (prefix && ftrace == stdout) { + if (prefix > 1) { + fprintf(ftrace, "[\033[31m%s\033[0m] ", names[box64_is32bits]); + } else { + fprintf(ftrace, "[%s] ", names[box64_is32bits]); + } + } + va_list args; + va_start(args, fmt); + vfprintf(ftrace, fmt, args); + fflush(ftrace); + va_end(args); +} diff --git a/src/os/os_wine.c b/src/os/os_wine.c index e7f34a99a5..1e61772a93 100644 --- a/src/os/os_wine.c +++ b/src/os/os_wine.c @@ -1,8 +1,11 @@ +#include +#include #include #include #include #include "os.h" +#include "wine/debug.h" #define HandleToULong(h) ((ULONG)(ULONG_PTR)(h)) @@ -54,11 +57,20 @@ void EmuX86Syscall(void* emu) // FIXME } +const char* GetBridgeName(void* p) +{ + return NULL; +} + const char* GetNativeName(void* p) { return NULL; } +void* GetNativeFnc(uintptr_t fnc) +{ + return NULL; +} void PersonalityAddrLimit32Bit(void) { @@ -193,3 +205,16 @@ int VolatileRangesContains(uintptr_t addr) { return 0; } + +void PrintfFtrace(int prefix, const char* fmt, ...) +{ + static char buf[1024] = { 0 }; + + char* p = buf; + strcpy(p, prefix > 1 ? "[\033[31mBOX64\033[0m] " : "[BOX64] "); + va_list args; + va_start(args, fmt); + vsprintf(p + strlen(p), fmt, args); + va_end(args); + __wine_dbg_output(p); +} diff --git a/wow64/CMakeLists.txt b/wow64/CMakeLists.txt index 31cd1a2151..8de346d4bd 100644 --- a/wow64/CMakeLists.txt +++ b/wow64/CMakeLists.txt @@ -49,6 +49,7 @@ set_target_properties(wow64_test_interpreter PROPERTIES COMPILE_DEFINITIONS "TES set(WOW64_BOX64CPU_SRC "${BOX64_ROOT}/src/custommem.c" "${BOX64_ROOT}/src/dynarec/arm64/arm64_immenc.c" + "${BOX64_ROOT}/src/dynarec/arm64/arm64_printer.c" "${BOX64_ROOT}/src/dynarec/arm64/dynarec_arm64_arch.c" "${BOX64_ROOT}/src/dynarec/arm64/dynarec_arm64_functions.c" "${BOX64_ROOT}/src/dynarec/arm64/dynarec_arm64_jmpnext.c" diff --git a/wow64/crt.c b/wow64/crt.c index dd4bde4e75..4e15239d87 100644 --- a/wow64/crt.c +++ b/wow64/crt.c @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -83,4 +84,18 @@ ldiv_t __cdecl ldiv(long num, long denom) void _assert (const char *_Message, const char *_File, unsigned _Line) { // NYI +} + +char* strerror(int e) +{ + return "error"; +} + +int snprintf(char* restrict s, size_t n, const char* restrict fmt, ...) +{ + va_list args; + va_start(args, fmt); + int result = _vsnprintf(s, n, fmt, args); + va_end(args); + return result; } \ No newline at end of file diff --git a/wow64/wowbox64.c b/wow64/wowbox64.c index 8177681b00..0aa10a223e 100644 --- a/wow64/wowbox64.c +++ b/wow64/wowbox64.c @@ -10,6 +10,7 @@ #include #include "compiler.h" +#include "debug.h" #include "os.h" #include "custommem.h" #include "dynablock.h" @@ -207,6 +208,8 @@ STATIC_ASSERT(offsetof(x64emu_t, win64_teb) == 3120, offset_of_b_must_be_4); LoadEnvVariables(); + printf_log(LOG_INFO, "libwowbox64.dll process initializing.\n"); + memset(bopcode, 0xc3, sizeof(bopcode)); memset(unxcode, 0xc3, sizeof(unxcode)); bopcode[0] = 0x2ecd; @@ -217,7 +220,7 @@ STATIC_ASSERT(offsetof(x64emu_t, win64_teb) == 3120, offset_of_b_must_be_4); if ((ULONG_PTR)bopcode >> 32 || (ULONG_PTR)unxcode >> 32) { - __wine_dbg_output( "box64cpu loaded above 4G, disabling\n" ); + printf_log(LOG_NONE, "box64cpu loaded above 4G, disabling\n"); return STATUS_INVALID_ADDRESS; }