Signed-off-by: Jinoh Kang jinoh.kang.kr@gmail.com --- configure | 6 ++++ configure.ac | 1 + dlls/ntdll/ntdll.spec | 2 ++ dlls/ntdll/unix/loader.c | 1 + dlls/ntdll/unix/virtual.c | 65 +++++++++++++++++++++++++++++++++++++++ include/config.h.in | 3 ++ 6 files changed, 78 insertions(+)
diff --git a/configure b/configure index ded6e71b815..d99e385120b 100755 --- a/configure +++ b/configure @@ -19000,6 +19000,12 @@ if test "x$ac_cv_func_mach_continuous_time" = xyes then : printf "%s\n" "#define HAVE_MACH_CONTINUOUS_TIME 1" >>confdefs.h
+fi +ac_fn_c_check_func "$LINENO" "madvise" "ac_cv_func_madvise" +if test "x$ac_cv_func_madvise" = xyes +then : + printf "%s\n" "#define HAVE_MADVISE 1" >>confdefs.h + fi ac_fn_c_check_func "$LINENO" "pipe2" "ac_cv_func_pipe2" if test "x$ac_cv_func_pipe2" = xyes diff --git a/configure.ac b/configure.ac index 4f7c7209da9..85a6f78d427 100644 --- a/configure.ac +++ b/configure.ac @@ -1942,6 +1942,7 @@ AC_CHECK_FUNCS(\ getrandom \ kqueue \ mach_continuous_time \ + madvise \ pipe2 \ port_create \ posix_fadvise \ diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec index e5a49ba1a1f..f85af7acebc 100644 --- a/dlls/ntdll/ntdll.spec +++ b/dlls/ntdll/ntdll.spec @@ -384,6 +384,7 @@ @ stdcall -syscall NtSetInformationProcess(long long ptr long) @ stdcall -syscall NtSetInformationThread(long long ptr long) @ stdcall -syscall NtSetInformationToken(long long ptr long) +@ stdcall -syscall NtSetInformationVirtualMemory(long long ptr ptr ptr long) @ stdcall -syscall NtSetIntervalProfile(long long) @ stdcall -syscall NtSetIoCompletion(ptr long long long long) @ stdcall -syscall NtSetLdtEntries(long int64 long int64) @@ -1405,6 +1406,7 @@ @ stdcall -private -syscall ZwSetInformationProcess(long long ptr long) NtSetInformationProcess @ stdcall -private -syscall ZwSetInformationThread(long long ptr long) NtSetInformationThread @ stdcall -private -syscall ZwSetInformationToken(long long ptr long) NtSetInformationToken +@ stdcall -private -syscall ZwSetInformationVirtualMemory(long long ptr ptr ptr long) NtSetInformationVirtualMemory @ stdcall -private -syscall ZwSetIntervalProfile(long long) NtSetIntervalProfile @ stdcall -private -syscall ZwSetIoCompletion(ptr long long long long) NtSetIoCompletion @ stdcall -private -syscall ZwSetLdtEntries(long int64 long int64) NtSetLdtEntries diff --git a/dlls/ntdll/unix/loader.c b/dlls/ntdll/unix/loader.c index f19d1d68dc7..d34f0b15d35 100644 --- a/dlls/ntdll/unix/loader.c +++ b/dlls/ntdll/unix/loader.c @@ -309,6 +309,7 @@ static void * const syscalls[] = NtSetInformationProcess, NtSetInformationThread, NtSetInformationToken, + NtSetInformationVirtualMemory, NtSetIntervalProfile, NtSetIoCompletion, NtSetLdtEntries, diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c index 5873a3e2335..e348e2a77e7 100644 --- a/dlls/ntdll/unix/virtual.c +++ b/dlls/ntdll/unix/virtual.c @@ -4968,6 +4968,71 @@ NTSTATUS WINAPI NtAreMappedFilesTheSame(PVOID addr1, PVOID addr2) }
+static NTSTATUS prefetch_memory( HANDLE process, ULONG_PTR count, + PMEMORY_RANGE_ENTRY addresses, ULONG flags ) +{ + ULONG_PTR i; + PVOID base; + SIZE_T size; + static int once; + + if (!once++) FIXME( "(process=%p,flags=%u) VmPrefetchInformation partial stub\n", process, flags ); + + if (process != NtCurrentProcess()) return STATUS_SUCCESS; + + for (i = 0; i < count; i++) + { + if (!addresses[i].NumberOfBytes) return STATUS_INVALID_PARAMETER_4; + } + + for (i = 0; i < count; i++) + { + MEMORY_RANGE_ENTRY entry; + memcpy(&entry, &addresses[i], sizeof(MEMORY_RANGE_ENTRY)); + + base = ROUND_ADDR( entry.VirtualAddress, page_mask ); + size = ROUND_SIZE( entry.VirtualAddress, entry.NumberOfBytes ); + +#ifdef HAVE_MADVISE + madvise(base, size, MADV_WILLNEED); +#else + (void)base; + (void)size; +#endif + } + + return STATUS_SUCCESS; +} + +/*********************************************************************** + * NtSetInformationVirtualMemory (NTDLL.@) + * ZwSetInformationVirtualMemory (NTDLL.@) + */ +NTSTATUS WINAPI NtSetInformationVirtualMemory( HANDLE process, + VIRTUAL_MEMORY_INFORMATION_CLASS info_class, + ULONG_PTR count, PMEMORY_RANGE_ENTRY addresses, + PVOID ptr, ULONG size ) +{ + TRACE("(%p, info_class=%d, %lu, %p, %p, %u)\n", + process, info_class, count, addresses, ptr, size); + + switch (info_class) + { + case VmPrefetchInformation: + if (!ptr) return STATUS_INVALID_PARAMETER_5; + if (size != sizeof(ULONG)) return STATUS_INVALID_PARAMETER_6; + if (!count) return STATUS_INVALID_PARAMETER_3; + if (!addresses) return STATUS_ACCESS_VIOLATION; + return prefetch_memory( process, count, addresses, *(ULONG *)ptr ); + + default: + FIXME("(%p,info_class=%d,%lu,%p,%p,%u) Unknown information class\n", + process, info_class, count, addresses, ptr, size); + return STATUS_INVALID_PARAMETER_2; + } +} + + /********************************************************************** * NtFlushInstructionCache (NTDLL.@) */ diff --git a/include/config.h.in b/include/config.h.in index 0fe50e8ce7c..234c3e1c8b5 100644 --- a/include/config.h.in +++ b/include/config.h.in @@ -293,6 +293,9 @@ /* Define to 1 if you have the <mach-o/loader.h> header file. */ #undef HAVE_MACH_O_LOADER_H
+/* Define to 1 if you have the `madvise' function. */ +#undef HAVE_MADVISE + /* Define to 1 if you have the <Metal/Metal.h> header file. */ #undef HAVE_METAL_METAL_H