From 4415653f842ae145178703a643cc1f62ee70b648 Mon Sep 17 00:00:00 2001 From: Martin Storsjo Date: Mon, 22 Jan 2018 00:05:09 +0200 Subject: [PATCH] ntdll: Implement NtFlushInstructionCache using __clear_cache where available. The configure check needs to be done with a more elaborate test than just AC_CHECK_FUNC, since it's a built-in function in clang and errors out if invoked with no parameters. Signed-off-by: Martin Storsjo Signed-off-by: Alexandre Julliard --- configure | 33 +++++++++++++++++++++++++++++++++ configure.ac | 8 ++++++++ dlls/ntdll/process.c | 26 +++++++++++++++----------- include/config.h.in | 4 ++++ 4 files changed, 60 insertions(+), 11 deletions(-) diff --git a/configure b/configure index f62b9e3516a..bcba635c2a8 100755 --- a/configure +++ b/configure @@ -17759,6 +17759,39 @@ $as_echo "#define HAVE___BUILTIN_POPCOUNT 1" >>confdefs.h fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __clear_cache" >&5 +$as_echo_n "checking for __clear_cache... " >&6; } +if ${ac_cv_have___clear_cache+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +__clear_cache((void*)0, (void*)0); return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_have___clear_cache="yes" +else + ac_cv_have___clear_cache="no" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_have___clear_cache" >&5 +$as_echo "$ac_cv_have___clear_cache" >&6; } +if test "$ac_cv_have___clear_cache" = "yes" +then + +$as_echo "#define HAVE___CLEAR_CACHE 1" >>confdefs.h + +fi + case $host_cpu in *i[3456789]86*) { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we need to define __i386__" >&5 diff --git a/configure.ac b/configure.ac index 9aa32280f41..db666b94507 100644 --- a/configure.ac +++ b/configure.ac @@ -2706,6 +2706,14 @@ then AC_DEFINE(HAVE___BUILTIN_POPCOUNT, 1, [Define to 1 if you have the `__builtin_popcount' built-in function.]) fi +AC_CACHE_CHECK([for __clear_cache], ac_cv_have___clear_cache, + AC_LINK_IFELSE([AC_LANG_PROGRAM(,[[__clear_cache((void*)0, (void*)0); return 0;]])], + [ac_cv_have___clear_cache="yes"], [ac_cv_have___clear_cache="no"])) +if test "$ac_cv_have___clear_cache" = "yes" +then + AC_DEFINE(HAVE___CLEAR_CACHE, 1, [Define to 1 if you have the `__clear_cache' (potentially built-in) function.]) +fi + dnl *** check for the need to define platform-specific symbols case $host_cpu in diff --git a/dlls/ntdll/process.c b/dlls/ntdll/process.c index f615ce2fea7..40034b4b092 100644 --- a/dlls/ntdll/process.c +++ b/dlls/ntdll/process.c @@ -653,20 +653,24 @@ NTSTATUS WINAPI NtSetInformationProcess( * NtFlushInstructionCache [NTDLL.@] * ZwFlushInstructionCache [NTDLL.@] */ -NTSTATUS WINAPI NtFlushInstructionCache( - IN HANDLE ProcessHandle, - IN LPCVOID BaseAddress, - IN SIZE_T Size) +NTSTATUS WINAPI NtFlushInstructionCache( HANDLE handle, const void *addr, SIZE_T size ) { - static int once; - if (!once++) - { #if defined(__x86_64__) || defined(__i386__) - TRACE("%p %p %ld - no-op on x86 and x86_64\n", ProcessHandle, BaseAddress, Size ); -#else - FIXME("%p %p %ld\n", ProcessHandle, BaseAddress, Size ); -#endif + /* no-op */ +#elif defined(HAVE___CLEAR_CACHE) + if (handle == GetCurrentProcess()) + { + __clear_cache( (char *)addr, (char *)addr + size ); } + else + { + static int once; + if (!once++) FIXME( "%p %p %ld other process not supported\n", handle, addr, size ); + } +#else + static int once; + if (!once++) FIXME( "%p %p %ld\n", handle, addr, size ); +#endif return STATUS_SUCCESS; } diff --git a/include/config.h.in b/include/config.h.in index 9224837393a..4db349c7d77 100644 --- a/include/config.h.in +++ b/include/config.h.in @@ -1407,6 +1407,10 @@ /* Define to 1 if you have the `__builtin_popcount' built-in function. */ #undef HAVE___BUILTIN_POPCOUNT +/* Define to 1 if you have the `__clear_cache' (potentially built-in) + function. */ +#undef HAVE___CLEAR_CACHE + /* Define to 1 if you have the `__res_getservers' function. */ #undef HAVE___RES_GETSERVERS