ntdll: Centralize initialization of the user shared data.

Signed-off-by: Alexandre Julliard <julliard@winehq.org>
feature/deterministic
Alexandre Julliard 2020-05-21 15:38:28 +02:00
parent ab350866e4
commit 0936606c38
4 changed files with 67 additions and 88 deletions

View File

@ -1105,22 +1105,8 @@ static inline void get_cpuinfo(SYSTEM_CPU_INFORMATION* info)
if(regs2[2] & (1 << 13)) info->FeatureSet |= CPU_FEATURE_CX128;
if(regs2[2] & (1 << 27)) info->FeatureSet |= CPU_FEATURE_XSAVE;
user_shared_data->ProcessorFeatures[PF_FLOATING_POINT_EMULATED] = !(regs2[3] & 1);
user_shared_data->ProcessorFeatures[PF_RDTSC_INSTRUCTION_AVAILABLE] = (regs2[3] >> 4) & 1;
user_shared_data->ProcessorFeatures[PF_PAE_ENABLED] = (regs2[3] >> 6) & 1;
user_shared_data->ProcessorFeatures[PF_COMPARE_EXCHANGE_DOUBLE] = (regs2[3] >> 8) & 1;
user_shared_data->ProcessorFeatures[PF_MMX_INSTRUCTIONS_AVAILABLE] = (regs2[3] >> 23) & 1;
user_shared_data->ProcessorFeatures[PF_XMMI_INSTRUCTIONS_AVAILABLE] = (regs2[3] >> 25) & 1;
user_shared_data->ProcessorFeatures[PF_XMMI64_INSTRUCTIONS_AVAILABLE] = (regs2[3] >> 26) & 1;
user_shared_data->ProcessorFeatures[PF_SSE3_INSTRUCTIONS_AVAILABLE] = regs2[2] & 1;
user_shared_data->ProcessorFeatures[PF_XSAVE_ENABLED] = (regs2[2] >> 27) & 1;
user_shared_data->ProcessorFeatures[PF_COMPARE_EXCHANGE128] = (regs2[2] >> 13) & 1;
if((regs2[3] & (1 << 26)) && (regs2[3] & (1 << 24)) && have_sse_daz_mode()) /* has SSE2 and FXSAVE/FXRSTOR */
{
info->FeatureSet |= CPU_FEATURE_DAZ;
user_shared_data->ProcessorFeatures[PF_SSE_DAZ_MODE_AVAILABLE] = TRUE;
}
if (regs[1] == AUTH && regs[3] == ENTI && regs[2] == CAMD)
{
@ -1137,10 +1123,6 @@ static inline void get_cpuinfo(SYSTEM_CPU_INFORMATION* info)
if (regs[0] >= 0x80000001)
{
do_cpuid(0x80000001, regs2); /* get vendor features */
user_shared_data->ProcessorFeatures[PF_VIRT_FIRMWARE_ENABLED] = (regs2[2] >> 2) & 1;
user_shared_data->ProcessorFeatures[PF_NX_ENABLED] = (regs2[3] >> 20) & 1;
user_shared_data->ProcessorFeatures[PF_3DNOW_INSTRUCTIONS_AVAILABLE] = (regs2[3] >> 31) & 1;
user_shared_data->ProcessorFeatures[PF_RDTSC_INSTRUCTION_AVAILABLE] = (regs2[3] >> 27) & 1;
if (regs2[2] & (1 << 2)) info->FeatureSet |= CPU_FEATURE_VIRT;
if (regs2[3] & (1 << 20)) info->FeatureSet |= CPU_FEATURE_NX;
if (regs2[3] & (1 << 27)) info->FeatureSet |= CPU_FEATURE_TSC;
@ -1159,14 +1141,11 @@ static inline void get_cpuinfo(SYSTEM_CPU_INFORMATION* info)
if(regs2[2] & (1 << 5)) info->FeatureSet |= CPU_FEATURE_VIRT;
if(regs2[3] & (1 << 21)) info->FeatureSet |= CPU_FEATURE_DS;
user_shared_data->ProcessorFeatures[PF_VIRT_FIRMWARE_ENABLED] = (regs2[2] >> 5) & 1;
do_cpuid(0x80000000, regs); /* get vendor cpuid level */
if (regs[0] >= 0x80000001)
{
do_cpuid(0x80000001, regs2); /* get vendor features */
user_shared_data->ProcessorFeatures[PF_NX_ENABLED] = (regs2[3] >> 20) & 1;
user_shared_data->ProcessorFeatures[PF_RDTSC_INSTRUCTION_AVAILABLE] = (regs2[3] >> 27) & 1;
if (regs2[3] & (1 << 20)) info->FeatureSet |= CPU_FEATURE_NX;
if (regs2[3] & (1 << 27)) info->FeatureSet |= CPU_FEATURE_TSC;
}
@ -1190,10 +1169,6 @@ static inline void get_cpuinfo(SYSTEM_CPU_INFORMATION* info)
size_t valSize;
int value;
valSize = sizeof(value);
if (sysctlbyname("hw.optional.floatingpoint", &value, &valSize, NULL, 0) == 0)
user_shared_data->ProcessorFeatures[PF_FLOATING_POINT_EMULATED] = !value;
valSize = sizeof(value);
if (sysctlbyname("hw.cpusubtype", &value, &valSize, NULL, 0) == 0)
{
@ -1260,16 +1235,8 @@ static inline void get_cpuinfo(SYSTEM_CPU_INFORMATION* info)
}
if (!_stricmp(line, "features"))
{
if (strstr(value, "vfpv3"))
{
info->FeatureSet |= CPU_FEATURE_ARM_VFP_32;
user_shared_data->ProcessorFeatures[PF_ARM_VFP_32_REGISTERS_AVAILABLE] = TRUE;
}
if (strstr(value, "neon"))
{
info->FeatureSet |= CPU_FEATURE_ARM_NEON;
user_shared_data->ProcessorFeatures[PF_ARM_NEON_INSTRUCTIONS_AVAILABLE] = TRUE;
}
if (strstr(value, "vfpv3")) info->FeatureSet |= CPU_FEATURE_ARM_VFP_32;
if (strstr(value, "neon")) info->FeatureSet |= CPU_FEATURE_ARM_NEON;
continue;
}
}
@ -1287,15 +1254,10 @@ static inline void get_cpuinfo(SYSTEM_CPU_INFORMATION* info)
valsize = sizeof(value);
if (!sysctlbyname("hw.floatingpoint", &value, &valsize, NULL, 0))
{
info->FeatureSet |= CPU_FEATURE_ARM_VFP_32;
user_shared_data->ProcessorFeatures[PF_ARM_VFP_32_REGISTERS_AVAILABLE] = value;
}
#else
FIXME("CPU Feature detection not implemented.\n");
#endif
if (info->Level >= 8)
user_shared_data->ProcessorFeatures[PF_ARM_V8_INSTRUCTIONS_AVAILABLE] = TRUE;
info->Architecture = PROCESSOR_ARCHITECTURE_ARM;
}
@ -1337,16 +1299,8 @@ static inline void get_cpuinfo(SYSTEM_CPU_INFORMATION* info)
}
if (!_stricmp(line, "Features"))
{
if (strstr(value, "crc32"))
{
info->FeatureSet |= CPU_FEATURE_ARM_V8_CRC32;
user_shared_data->ProcessorFeatures[PF_ARM_V8_CRC32_INSTRUCTIONS_AVAILABLE] = TRUE;
}
if (strstr(value, "aes"))
{
info->FeatureSet |= CPU_FEATURE_ARM_V8_CRYPTO;
user_shared_data->ProcessorFeatures[PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE] = TRUE;
}
if (strstr(value, "crc32")) info->FeatureSet |= CPU_FEATURE_ARM_V8_CRC32;
if (strstr(value, "aes")) info->FeatureSet |= CPU_FEATURE_ARM_V8_CRYPTO;
continue;
}
}
@ -1356,7 +1310,6 @@ static inline void get_cpuinfo(SYSTEM_CPU_INFORMATION* info)
FIXME("CPU Feature detection not implemented.\n");
#endif
info->Level = max(info->Level, 8);
user_shared_data->ProcessorFeatures[PF_ARM_V8_INSTRUCTIONS_AVAILABLE] = TRUE;
info->Architecture = PROCESSOR_ARCHITECTURE_ARM64;
}

View File

@ -2261,7 +2261,6 @@ static void test_queryvirtualmemory(void)
ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status);
ok(readcount == sizeof(MEMORY_BASIC_INFORMATION), "Expected to read %d bytes, got %ld\n",(int)sizeof(MEMORY_BASIC_INFORMATION),readcount);
ok(mbi.AllocationBase == user_shared_data, "mbi.AllocationBase is 0x%p, expected 0x%p\n", mbi.AllocationBase, user_shared_data);
todo_wine
ok(mbi.AllocationProtect == PAGE_READONLY, "mbi.AllocationProtect is 0x%x, expected 0x%x\n", mbi.AllocationProtect, PAGE_READONLY);
ok(mbi.State == MEM_COMMIT, "mbi.State is 0x%x, expected 0x%X\n", mbi.State, MEM_COMMIT);
ok(mbi.Protect == PAGE_READONLY, "mbi.Protect is 0x%x\n", mbi.Protect);

View File

@ -53,7 +53,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(thread);
#endif
struct _KUSER_SHARED_DATA *user_shared_data = NULL;
static size_t user_shared_data_size;
void (WINAPI *kernel32_start_process)(LPTHREAD_START_ROUTINE,void*) = NULL;
@ -183,6 +182,64 @@ int __cdecl __wine_dbg_output( const char *str )
return unix_funcs->dbg_output( str );
}
static void fill_user_shared_data( struct _KUSER_SHARED_DATA *data )
{
RTL_OSVERSIONINFOEXW version;
SYSTEM_CPU_INFORMATION sci;
SYSTEM_BASIC_INFORMATION sbi;
BOOLEAN *features = data->ProcessorFeatures;
version.dwOSVersionInfoSize = sizeof(version);
RtlGetVersion( &version );
virtual_get_system_info( &sbi );
NtQuerySystemInformation( SystemCpuInformation, &sci, sizeof(sci), NULL );
data->TickCountMultiplier = 1 << 24;
data->LargePageMinimum = 2 * 1024 * 1024;
data->NtBuildNumber = version.dwBuildNumber;
data->NtProductType = version.wProductType;
data->ProductTypeIsValid = TRUE;
data->NativeProcessorArchitecture = sci.Architecture;
data->NtMajorVersion = version.dwMajorVersion;
data->NtMinorVersion = version.dwMinorVersion;
data->SuiteMask = version.wSuiteMask;
data->NumberOfPhysicalPages = sbi.MmNumberOfPhysicalPages;
wcscpy( data->NtSystemRoot, windows_dir );
switch (sci.Architecture)
{
case PROCESSOR_ARCHITECTURE_INTEL:
case PROCESSOR_ARCHITECTURE_AMD64:
features[PF_COMPARE_EXCHANGE_DOUBLE] = !!(sci.FeatureSet & CPU_FEATURE_CX8);
features[PF_MMX_INSTRUCTIONS_AVAILABLE] = !!(sci.FeatureSet & CPU_FEATURE_MMX);
features[PF_XMMI_INSTRUCTIONS_AVAILABLE] = !!(sci.FeatureSet & CPU_FEATURE_SSE);
features[PF_3DNOW_INSTRUCTIONS_AVAILABLE] = !!(sci.FeatureSet & CPU_FEATURE_3DNOW);
features[PF_RDTSC_INSTRUCTION_AVAILABLE] = !!(sci.FeatureSet & CPU_FEATURE_TSC);
features[PF_PAE_ENABLED] = !!(sci.FeatureSet & CPU_FEATURE_PAE);
features[PF_XMMI64_INSTRUCTIONS_AVAILABLE] = !!(sci.FeatureSet & CPU_FEATURE_SSE2);
features[PF_SSE3_INSTRUCTIONS_AVAILABLE] = !!(sci.FeatureSet & CPU_FEATURE_SSE3);
features[PF_XSAVE_ENABLED] = !!(sci.FeatureSet & CPU_FEATURE_XSAVE);
features[PF_COMPARE_EXCHANGE128] = !!(sci.FeatureSet & CPU_FEATURE_CX128);
features[PF_SSE_DAZ_MODE_AVAILABLE] = !!(sci.FeatureSet & CPU_FEATURE_DAZ);
features[PF_NX_ENABLED] = !!(sci.FeatureSet & CPU_FEATURE_NX);
features[PF_SECOND_LEVEL_ADDRESS_TRANSLATION] = !!(sci.FeatureSet & CPU_FEATURE_2NDLEV);
features[PF_VIRT_FIRMWARE_ENABLED] = !!(sci.FeatureSet & CPU_FEATURE_VIRT);
features[PF_RDWRFSGSBASE_AVAILABLE] = !!(sci.FeatureSet & CPU_FEATURE_RDFS);
features[PF_FASTFAIL_AVAILABLE] = TRUE;
break;
case PROCESSOR_ARCHITECTURE_ARM:
features[PF_ARM_VFP_32_REGISTERS_AVAILABLE] = !!(sci.FeatureSet & CPU_FEATURE_ARM_VFP_32);
features[PF_ARM_NEON_INSTRUCTIONS_AVAILABLE] = !!(sci.FeatureSet & CPU_FEATURE_ARM_NEON);
features[PF_ARM_V8_INSTRUCTIONS_AVAILABLE] = (sci.Level >= 8);
break;
case PROCESSOR_ARCHITECTURE_ARM64:
features[PF_ARM_V8_INSTRUCTIONS_AVAILABLE] = TRUE;
features[PF_ARM_V8_CRC32_INSTRUCTIONS_AVAILABLE] = !!(sci.FeatureSet & CPU_FEATURE_ARM_V8_CRC32);
features[PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE] = !!(sci.FeatureSet & CPU_FEATURE_ARM_V8_CRYPTO);
break;
}
}
HANDLE user_shared_data_init_done(void)
{
static const WCHAR wine_usdW[] = {'\\','K','e','r','n','e','l','O','b','j','e','c','t','s',
@ -194,11 +251,9 @@ HANDLE user_shared_data_init_done(void)
HANDLE section;
SIZE_T size;
void *addr;
ULONG old_prot;
int res, fd, needs_close;
section_size.HighPart = 0;
section_size.LowPart = user_shared_data_size;
section_size.QuadPart = sizeof(*user_shared_data);
RtlInitUnicodeString( &wine_usd_str, wine_usdW );
InitializeObjectAttributes( &attr, &wine_usd_str, OBJ_OPENIF, NULL, NULL );
@ -213,8 +268,7 @@ HANDLE user_shared_data_init_done(void)
if (status != STATUS_OBJECT_NAME_EXISTS)
{
addr = NULL;
size = user_shared_data_size;
size = sizeof(*user_shared_data);
if ((status = NtMapViewOfSection( section, NtCurrentProcess(), &addr, 0, 0, 0,
&size, 0, 0, PAGE_READWRITE )))
{
@ -222,16 +276,12 @@ HANDLE user_shared_data_init_done(void)
exit(1);
}
memcpy( addr, user_shared_data, user_shared_data_size );
fill_user_shared_data( addr );
NtUnmapViewOfSection( NtCurrentProcess(), addr );
}
addr = user_shared_data;
size = user_shared_data_size;
NtProtectVirtualMemory( NtCurrentProcess(), &addr, &size, PAGE_READONLY, &old_prot );
if ((res = server_get_unix_fd( section, 0, &fd, &needs_close, NULL, NULL )) ||
(user_shared_data != mmap( user_shared_data, user_shared_data_size,
(user_shared_data != mmap( user_shared_data, sizeof(*user_shared_data),
PROT_READ, MAP_SHARED | MAP_FIXED, fd, 0 )))
{
MESSAGE( "wine: failed to remap the process USD: %d\n", res );
@ -251,11 +301,9 @@ HANDLE user_shared_data_init_done(void)
*/
TEB *thread_init(void)
{
SYSTEM_BASIC_INFORMATION sbi;
TEB *teb;
void *addr;
SIZE_T size;
LARGE_INTEGER now;
NTSTATUS status;
struct ntdll_thread_data *thread_data;
@ -266,15 +314,13 @@ TEB *thread_init(void)
addr = (void *)0x7ffe0000;
size = 0x1000;
status = NtAllocateVirtualMemory( NtCurrentProcess(), &addr, 0, &size,
MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE );
MEM_RESERVE|MEM_COMMIT, PAGE_READONLY );
if (status)
{
MESSAGE( "wine: failed to map the shared user data: %08x\n", status );
exit(1);
}
user_shared_data = addr;
user_shared_data_size = size;
wcscpy( user_shared_data->NtSystemRoot, windows_dir );
/* allocate and initialize the PEB and initial TEB */
@ -317,20 +363,7 @@ TEB *thread_init(void)
unix_funcs->dbg_init();
unix_funcs->get_paths( &build_dir, &data_dir, &config_dir );
/* initialize time values in user_shared_data */
NtQuerySystemTime( &now );
user_shared_data->SystemTime.LowPart = now.u.LowPart;
user_shared_data->SystemTime.High1Time = user_shared_data->SystemTime.High2Time = now.u.HighPart;
user_shared_data->u.TickCountQuad = (now.QuadPart - server_start_time) / 10000;
user_shared_data->u.TickCount.High2Time = user_shared_data->u.TickCount.High1Time;
user_shared_data->TickCountLowDeprecated = user_shared_data->u.TickCount.LowPart;
user_shared_data->TickCountMultiplier = 1 << 24;
fill_cpu_info();
virtual_get_system_info( &sbi );
user_shared_data->NumberOfPhysicalPages = sbi.MmNumberOfPhysicalPages;
return teb;
}

View File

@ -540,12 +540,6 @@ done:
NtCurrentTeb()->Peb->OSBuildNumber = current_version->dwBuildNumber;
NtCurrentTeb()->Peb->OSPlatformId = current_version->dwPlatformId;
user_shared_data->NtProductType = current_version->wProductType;
user_shared_data->ProductTypeIsValid = TRUE;
user_shared_data->NtMajorVersion = current_version->dwMajorVersion;
user_shared_data->NtMinorVersion = current_version->dwMinorVersion;
user_shared_data->SuiteMask = current_version->wSuiteMask;
TRACE( "got %d.%d platform %d build %x name %s service pack %d.%d product %d\n",
current_version->dwMajorVersion, current_version->dwMinorVersion,
current_version->dwPlatformId, current_version->dwBuildNumber,