Project

General

Profile

patch0.patch

ucrtbase-fread-workaround - Anonymous, 09/30/2015 12:13 AM

View differences:

Source/Core/Common/Common.vcxproj
120 120
    <ClCompile Include="Thread.cpp" />
121 121
    <ClCompile Include="Timer.cpp" />
122 122
    <ClCompile Include="TraversalClient.cpp" />
123
    <ClCompile Include="ucrtFreadWorkaround.cpp" />
123 124
    <ClCompile Include="Version.cpp" />
124 125
    <ClCompile Include="x64ABI.cpp" />
125 126
    <ClCompile Include="x64Analyzer.cpp" />
126 127
    <ClCompile Include="x64CPUDetect.cpp" />
127 128
    <ClCompile Include="x64Emitter.cpp" />
128 129
    <ClCompile Include="x64FPURoundMode.cpp" />
129
    <ClCompile Include="XSaveWorkaround.cpp" />
130 130
    <ClCompile Include="Crypto\bn.cpp" />
131 131
    <ClCompile Include="Crypto\ec.cpp" />
132 132
    <ClCompile Include="Logging\LogManager.cpp" />
......
148 148
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
149 149
  <ImportGroup Label="ExtensionTargets">
150 150
  </ImportGroup>
151
</Project>
151
</Project>
Source/Core/Common/Common.vcxproj.filters
115 115
    <ClCompile Include="Logging\LogManager.cpp">
116 116
      <Filter>Logging</Filter>
117 117
    </ClCompile>
118
    <ClCompile Include="XSaveWorkaround.cpp" />
119 118
    <ClCompile Include="GekkoDisassembler.cpp" />
120 119
    <ClCompile Include="JitRegister.cpp" />
121 120
    <ClCompile Include="TraversalClient.cpp" />
122 121
    <ClCompile Include="Logging\ConsoleListenerWin.cpp">
123 122
      <Filter>Logging</Filter>
124 123
    </ClCompile>
124
    <ClCompile Include="ucrtFreadWorkaround.cpp" />
125 125
  </ItemGroup>
126 126
  <ItemGroup>
127 127
    <Text Include="CMakeLists.txt" />
128 128
  </ItemGroup>
129
</Project>
129
</Project>
Source/Core/Common/XSaveWorkaround.cpp
1
// Copyright 2014 Dolphin Emulator Project
2
// Licensed under GPLv2+
3
// Refer to the license.txt file included.
4

  
5
#if defined(_WIN32)
6

  
7
#include <math.h>
8
#include <Windows.h>
9

  
10
typedef decltype(&GetEnabledXStateFeatures) GetEnabledXStateFeatures_t;
11

  
12
int __cdecl EnableXSaveWorkaround()
13
{
14
	// Some Windows environments may have hardware support for AVX/FMA,
15
	// but the OS does not support it. The CRT math library does not support
16
	// this scenario, so we have to manually tell it not to use FMA3
17
	// instructions.
18

  
19
	// The API name is somewhat misleading - we're testing for OS support
20
	// here.
21
	if (!IsProcessorFeaturePresent(PF_XSAVE_ENABLED))
22
	{
23
		_set_FMA3_enable(0);
24
		return 0;
25
	}
26

  
27
	// Even if XSAVE feature is enabled, we have to see if
28
	// GetEnabledXStateFeatures function is present, and see what it says about
29
	// AVX state.
30
	auto kernel32Handle = GetModuleHandle(TEXT("kernel32.dll"));
31
	if (kernel32Handle == nullptr)
32
	{
33
		std::abort();
34
	}
35

  
36
	auto pGetEnabledXStateFeatures = (GetEnabledXStateFeatures_t)GetProcAddress(
37
		kernel32Handle, "GetEnabledXStateFeatures");
38
	if (pGetEnabledXStateFeatures == nullptr ||
39
		(pGetEnabledXStateFeatures() & XSTATE_MASK_AVX) == 0)
40
	{
41
		_set_FMA3_enable(0);
42
	}
43

  
44
	return 0;
45
}
46

  
47
// Create a segment which is recognized by the linker to be part of the CRT
48
// initialization. XI* = C startup, XC* = C++ startup. "A" placement is reserved
49
// for system use. Thus, the earliest we can get is XIB (C startup is before
50
// C++).
51
#pragma section(".CRT$XIB", read)
52

  
53
// Place a symbol in the special segment, make it have C linkage so that
54
// referencing it doesn't require ugly decorated names.
55
// Use /include:XSaveWorkaround linker flag to enable this.
56
extern "C" {
57
	__declspec(allocate(".CRT$XIB"))
58
	decltype(&EnableXSaveWorkaround) XSaveWorkaround = EnableXSaveWorkaround;
59
};
60

  
61
#endif
Source/Core/Common/ucrtFreadWorkaround.cpp
1
// Copyright 2014 Dolphin Emulator Project
2
// Licensed under GPLv2+
3
// Refer to the license.txt file included.
4

  
5
#if defined(_WIN32)
6

  
7
#include <Windows.h>
8

  
9
int __cdecl EnableucrtFreadWorkaround()
10
{
11
    // This patches ucrtbase such that fseek will alway
12
    // synchronize the file object's internal buffer.
13

  
14
	auto ucrtbase = GetModuleHandle(TEXT("ucrtbase.dll"));
15
    auto ucrtbase_pe = (PIMAGE_NT_HEADERS)((uintptr_t)ucrtbase + ((PIMAGE_DOS_HEADER)ucrtbase)->e_lfanew);
16
	if (ucrtbase == nullptr || ucrtbase_pe->OptionalHeader.CheckSum != 0xF61ED)
17
	{
18
		std::abort();
19
	}
20

  
21
    void *patch_addr = (void *)((uintptr_t)ucrtbase + 0x6AE7B);
22
    size_t patch_size = 5;
23

  
24
    DWORD old_protect;
25
    if (!VirtualProtect(patch_addr, patch_size, PAGE_EXECUTE_READWRITE, &old_protect))
26
    {
27
        std::abort();
28
    }
29

  
30
    memset(patch_addr, 0x90, patch_size);
31

  
32
    VirtualProtect(patch_addr, patch_size, old_protect, &old_protect);
33

  
34
    FlushInstructionCache(GetCurrentProcess(), patch_addr, patch_size);
35

  
36
	return 0;
37
}
38

  
39
// Create a segment which is recognized by the linker to be part of the CRT
40
// initialization. XI* = C startup, XC* = C++ startup. "A" placement is reserved
41
// for system use. Thus, the earliest we can get is XIB (C startup is before
42
// C++).
43
#pragma section(".CRT$XIB", read)
44

  
45
// Place a symbol in the special segment, make it have C linkage so that
46
// referencing it doesn't require ugly decorated names.
47
// Use /include:EnableucrtFreadWorkaround linker flag to enable this.
48
extern "C" {
49
	__declspec(allocate(".CRT$XIB"))
50
	decltype(&EnableucrtFreadWorkaround) ucrtFreadWorkaround = EnableucrtFreadWorkaround;
51
};
52

  
53
#endif
Source/VSProps/Base.props
122 122
    </Link>
123 123
    <!--Link Base:Application-->
124 124
    <Link Condition="'$(ConfigurationType)'=='Application'">
125
      <!--See Common/EnableXSaveWorkaround.cpp-->
126
      <ForceSymbolReferences>XSaveWorkaround</ForceSymbolReferences>
125
      <!--See Common/ucrtFreadWorkaround.cpp-->
126
      <ForceSymbolReferences>ucrtFreadWorkaround</ForceSymbolReferences>
127 127
    </Link>
128 128
    <Lib>
129 129
      <TreatLibWarningAsErrors>true</TreatLibWarningAsErrors>