Commit 1b823e5f authored by Alexandre Julliard's avatar Alexandre Julliard

ntdll: Support the MEM_EXTENDED_PARAMETER_EC_CODE attribute.

parent 5b6e82f0
......@@ -37,6 +37,8 @@ static ULONG64 (WINAPI *pRtlGetEnabledExtendedFeatures)(ULONG64);
static NTSTATUS (WINAPI *pRtlFreeUserStack)(void *);
static void * (WINAPI *pRtlFindExportedRoutineByName)(HMODULE,const char*);
static BOOL (WINAPI *pIsWow64Process)(HANDLE, PBOOL);
static NTSTATUS (WINAPI *pRtlGetNativeSystemInformation)(SYSTEM_INFORMATION_CLASS, PVOID, ULONG, PULONG);
static BOOLEAN (WINAPI *pRtlIsEcCode)(const void *);
static NTSTATUS (WINAPI *pNtAllocateVirtualMemoryEx)(HANDLE, PVOID *, SIZE_T *, ULONG, ULONG,
MEM_EXTENDED_PARAMETER *, ULONG);
static NTSTATUS (WINAPI *pNtMapViewOfSectionEx)(HANDLE, HANDLE, PVOID *, const LARGE_INTEGER *, SIZE_T *,
......@@ -291,6 +293,7 @@ static void check_region_size_(void *p, SIZE_T s, unsigned int line)
static void test_NtAllocateVirtualMemoryEx(void)
{
MEM_EXTENDED_PARAMETER ext;
SIZE_T size, size2;
char *p, *p1, *p2;
NTSTATUS status;
......@@ -421,6 +424,73 @@ static void test_NtAllocateVirtualMemoryEx(void)
status = NtFreeVirtualMemory(NtCurrentProcess(), (void **)&p2, &size2, MEM_RELEASE);
ok(status == STATUS_SUCCESS, "Unexpected status %08lx.\n", status);
}
memset( &ext, 0, sizeof(ext) );
ext.Type = MemExtendedParameterAttributeFlags;
ext.ULong = MEM_EXTENDED_PARAMETER_EC_CODE;
size = 0x10000;
addr1 = NULL;
status = pNtAllocateVirtualMemoryEx( NtCurrentProcess(), &addr1, &size, MEM_RESERVE,
PAGE_EXECUTE_READWRITE, &ext, 1 );
#ifdef __x86_64__
if (pRtlGetNativeSystemInformation)
{
SYSTEM_CPU_INFORMATION cpu_info;
pRtlGetNativeSystemInformation( SystemCpuInformation, &cpu_info, sizeof(cpu_info), NULL );
if (cpu_info.ProcessorArchitecture == PROCESSOR_ARCHITECTURE_ARM64)
{
ok(status == STATUS_SUCCESS, "Unexpected status %08lx.\n", status);
if (pRtlIsEcCode) ok( pRtlIsEcCode( addr1 ), "not EC code %p\n", addr1 );
size = 0;
NtFreeVirtualMemory( NtCurrentProcess(), &addr1, &size, MEM_RELEASE );
size = 0x10000;
addr1 = NULL;
status = pNtAllocateVirtualMemoryEx( NtCurrentProcess(), &addr1, &size, MEM_RESERVE,
PAGE_EXECUTE_READWRITE, NULL, 0 );
ok(status == STATUS_SUCCESS, "Unexpected status %08lx.\n", status);
if (pRtlIsEcCode) ok( !pRtlIsEcCode( addr1 ), "EC code %p\n", addr1 );
size = 0x1000;
status = pNtAllocateVirtualMemoryEx( NtCurrentProcess(), &addr1, &size, MEM_COMMIT,
PAGE_EXECUTE_READWRITE, &ext, 1 );
ok(status == STATUS_SUCCESS, "Unexpected status %08lx.\n", status);
if (pRtlIsEcCode)
{
ok( pRtlIsEcCode( addr1 ), "not EC code %p\n", addr1 );
ok( !pRtlIsEcCode( (char *)addr1 + 0x1000 ), "EC code %p\n", (char *)addr1 + 0x1000 );
}
size = 0x2000;
status = pNtAllocateVirtualMemoryEx( NtCurrentProcess(), &addr1, &size, MEM_COMMIT,
PAGE_EXECUTE_READWRITE, NULL, 0 );
ok(status == STATUS_SUCCESS, "Unexpected status %08lx.\n", status);
if (pRtlIsEcCode)
{
ok( pRtlIsEcCode( addr1 ), "not EC code %p\n", addr1 );
ok( !pRtlIsEcCode( (char *)addr1 + 0x1000 ), "EC code %p\n", (char *)addr1 + 0x1000 );
}
NtFreeVirtualMemory( NtCurrentProcess(), &addr1, &size, MEM_DECOMMIT );
if (pRtlIsEcCode) ok( pRtlIsEcCode( addr1 ), "not EC code %p\n", addr1 );
size = 0x2000;
ext.ULong = 0;
status = pNtAllocateVirtualMemoryEx( NtCurrentProcess(), &addr1, &size, MEM_COMMIT,
PAGE_EXECUTE_READWRITE, &ext, 1 );
ok(status == STATUS_SUCCESS, "Unexpected status %08lx.\n", status);
if (pRtlIsEcCode)
{
ok( pRtlIsEcCode( addr1 ), "not EC code %p\n", addr1 );
ok( !pRtlIsEcCode( (char *)addr1 + 0x1000 ), "EC code %p\n", (char *)addr1 + 0x1000 );
}
size = 0;
NtFreeVirtualMemory( NtCurrentProcess(), &addr1, &size, MEM_RELEASE );
return;
}
}
#endif
ok(status == STATUS_INVALID_PARAMETER, "Unexpected status %08lx.\n", status);
}
static void test_NtAllocateVirtualMemoryEx_address_requirements(void)
......@@ -1928,6 +1998,8 @@ START_TEST(virtual)
pRtlFreeUserStack = (void *)GetProcAddress(mod, "RtlFreeUserStack");
pRtlFindExportedRoutineByName = (void *)GetProcAddress(mod, "RtlFindExportedRoutineByName");
pRtlGetEnabledExtendedFeatures = (void *)GetProcAddress(mod, "RtlGetEnabledExtendedFeatures");
pRtlGetNativeSystemInformation = (void *)GetProcAddress(mod, "RtlGetNativeSystemInformation");
pRtlIsEcCode = (void *)GetProcAddress(mod, "RtlIsEcCode");
pNtAllocateVirtualMemoryEx = (void *)GetProcAddress(mod, "NtAllocateVirtualMemoryEx");
pNtMapViewOfSectionEx = (void *)GetProcAddress(mod, "NtMapViewOfSectionEx");
pNtSetInformationVirtualMemory = (void *)GetProcAddress(mod, "NtSetInformationVirtualMemory");
......
......@@ -1008,7 +1008,6 @@ static inline UINT64 maskbits( size_t idx )
/***********************************************************************
* set_arm64ec_range
*/
#ifdef __aarch64__
static void set_arm64ec_range( const void *addr, size_t size )
{
size_t idx = (size_t)addr >> page_shift;
......@@ -1024,7 +1023,7 @@ static void set_arm64ec_range( const void *addr, size_t size )
}
else arm64ec_map[pos] |= maskbits( idx ) & ~maskbits( end );
}
#endif
/***********************************************************************
* clear_arm64ec_range
......@@ -3958,6 +3957,8 @@ static NTSTATUS allocate_virtual_memory( void **ret, SIZE_T *size_ptr, ULONG typ
return STATUS_INVALID_PARAMETER;
}
if (!arm64ec_map && (attributes & MEM_EXTENDED_PARAMETER_EC_CODE)) return STATUS_INVALID_PARAMETER;
/* Reserve the memory */
server_enter_uninterrupted_section( &virtual_mutex, &sigset );
......@@ -4000,6 +4001,8 @@ static NTSTATUS allocate_virtual_memory( void **ret, SIZE_T *size_ptr, ULONG typ
}
}
if (!status && (attributes & MEM_EXTENDED_PARAMETER_EC_CODE)) set_arm64ec_range( base, size );
if (!status) VIRTUAL_DEBUG_DUMP_VIEW( view );
server_leave_uninterrupted_section( &virtual_mutex, &sigset );
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment