From: Yonggang L. <luo...@gm...> - 2024-12-13 18:32:27
|
Always include uintptr_t for win32, as we use uintptr_t. sizeof(unsigned long int) is 4 on mingw 64bit, use uintptr_t int instead, that's the same with MSVC 64bit __clang__ for MSVC support for GCC inline assembly _MSC_VER for PLAT_amd64_win64 does not support inline assembly, use stub instead, may be fixed use machine code. The compiling for MSVC,CLANG,GCC are checked Signed-off-by: Yonggang Luo <luo...@gm...> --- include/valgrind.h.in | 121 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 116 insertions(+), 5 deletions(-) diff --git a/include/valgrind.h.in b/include/valgrind.h.in index bc18f40f7..e4867c333 100644 --- a/include/valgrind.h.in +++ b/include/valgrind.h.in @@ -94,6 +94,10 @@ #include <stdarg.h> +#ifdef _WIN32 +#include <stdint.h> +#endif + /* Nb: this file might be included in a file compiled with -ansi. So we can't use C++ style "//" comments nor the "asm" keyword (instead use "__asm__"). */ @@ -403,12 +407,11 @@ valgrind_do_client_request_expr(uintptr_t _zzq_default, uintptr_t _zzq_request, #endif /* PLAT_x86_win32 */ -/* ----------------- amd64-{linux,darwin,solaris} --------------- */ +/* ----------------- amd64-{linux,darwin,solaris,freebsd} --------------- */ #if defined(PLAT_amd64_linux) || defined(PLAT_amd64_darwin) \ || defined(PLAT_amd64_solaris) \ - || defined(PLAT_amd64_freebsd) \ - || (defined(PLAT_amd64_win64) && defined(__GNUC__)) + || defined(PLAT_amd64_freebsd) typedef struct { @@ -468,14 +471,122 @@ typedef ); \ } while (0) -#endif /* PLAT_amd64_linux || PLAT_amd64_darwin || PLAT_amd64_solaris */ +#endif /* defined(PLAT_amd64_linux) || defined(PLAT_amd64_darwin) \ + || defined(PLAT_amd64_solaris) \ + || defined(PLAT_amd64_freebsd) */ /* ------------------------- amd64-Win64 ------------------------- */ -#if defined(PLAT_amd64_win64) && !defined(__GNUC__) +#if defined(PLAT_amd64_win64) + +typedef + struct { + uintptr_t nraddr; /* where's the code? */ + } + OrigFn; + +#if defined(__GNUC__) || defined(__clang__) + +#define __SPECIAL_INSTRUCTION_PREAMBLE \ + "rolq $3, %%rdi ; rolq $13, %%rdi\n\t" \ + "rolq $61, %%rdi ; rolq $51, %%rdi\n\t" + +#define VALGRIND_DO_CLIENT_REQUEST_EXPR( \ + _zzq_default, _zzq_request, \ + _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ + __extension__ \ + ({ volatile uintptr_t _zzq_args[6]; \ + volatile uintptr_t _zzq_result; \ + _zzq_args[0] = (uintptr_t)(_zzq_request); \ + _zzq_args[1] = (uintptr_t)(_zzq_arg1); \ + _zzq_args[2] = (uintptr_t)(_zzq_arg2); \ + _zzq_args[3] = (uintptr_t)(_zzq_arg3); \ + _zzq_args[4] = (uintptr_t)(_zzq_arg4); \ + _zzq_args[5] = (uintptr_t)(_zzq_arg5); \ + __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ + /* %RDX = client_request ( %RAX ) */ \ + "xchgq %%rbx,%%rbx" \ + : "=d" (_zzq_result) \ + : "a" (&_zzq_args[0]), "0" (_zzq_default) \ + : "cc", "memory" \ + ); \ + _zzq_result; \ + }) + +#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \ + { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \ + volatile uintptr_t __addr; \ + __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ + /* %RAX = guest_NRADDR */ \ + "xchgq %%rcx,%%rcx" \ + : "=a" (__addr) \ + : \ + : "cc", "memory" \ + ); \ + _zzq_orig->nraddr = __addr; \ + } + +#define VALGRIND_CALL_NOREDIR_RAX \ + __SPECIAL_INSTRUCTION_PREAMBLE \ + /* call-noredir *%RAX */ \ + "xchgq %%rdx,%%rdx\n\t" + +#define VALGRIND_VEX_INJECT_IR() \ + do { \ + __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ + "xchgq %%rdi,%%rdi\n\t" \ + : : : "cc", "memory" \ + ); \ + } while (0) + +#elif defined(_MSC_VER) + +#define VALGRIND_DO_CLIENT_REQUEST_EXPR( \ + _zzq_default, _zzq_request, \ + _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ + valgrind_do_client_request_expr((uintptr_t)(_zzq_default), \ + (uintptr_t)(_zzq_request), (uintptr_t)(_zzq_arg1), \ + (uintptr_t)(_zzq_arg2), (uintptr_t)(_zzq_arg3), \ + (uintptr_t)(_zzq_arg4), (uintptr_t)(_zzq_arg5)) + +static __inline uintptr_t +valgrind_do_client_request_expr(uintptr_t _zzq_default, uintptr_t _zzq_request, + uintptr_t _zzq_arg1, uintptr_t _zzq_arg2, + uintptr_t _zzq_arg3, uintptr_t _zzq_arg4, + uintptr_t _zzq_arg5) +{ + volatile uintptr_t _zzq_args[6]; + volatile uintptr_t _zzq_result = 0; + _zzq_args[0] = (uintptr_t)(_zzq_request); + _zzq_args[1] = (uintptr_t)(_zzq_arg1); + _zzq_args[2] = (uintptr_t)(_zzq_arg2); + _zzq_args[3] = (uintptr_t)(_zzq_arg3); + _zzq_args[4] = (uintptr_t)(_zzq_arg4); + _zzq_args[5] = (uintptr_t)(_zzq_arg5); + /* TODO: use machine code to support for MSVC 64 bit*/ + return _zzq_result; +} + +#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \ + { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \ + volatile uintptr_t __addr; \ + /* TODO: use machine code to support for MSVC 64 bit*/ \ + _zzq_orig->nraddr = __addr; \ + } + +#define VALGRIND_CALL_NOREDIR_RAX ERROR + +#define VALGRIND_VEX_INJECT_IR() \ + do { \ + /* TODO: use machine code to support for MSVC 64 bit*/ \ +} while (0) + +#else /* !defined(__GNUC__) && !defined(__clang__) && !defined(_MSC_VER) */ #error Unsupported compiler. +#endif /* defined(__GNUC__) || defined(__clang__) */ + #endif /* PLAT_amd64_win64 */ /* ------------------------ ppc32-linux ------------------------ */ -- 2.47.1.windows.1 |