summaryrefslogtreecommitdiff
path: root/src/pal
diff options
context:
space:
mode:
authorJiyoung Yun <jy910.yun@samsung.com>2017-06-13 18:47:36 +0900
committerJiyoung Yun <jy910.yun@samsung.com>2017-06-13 18:47:36 +0900
commit61d6a817e39d3bae0f47dbc09838d51db22a5d30 (patch)
treecb37caa1784bc738b976273335d6ed04a7cc80b0 /src/pal
parent5b975f8233e8c8d17b215372f89ca713b45d6a0b (diff)
downloadcoreclr-61d6a817e39d3bae0f47dbc09838d51db22a5d30.tar.gz
coreclr-61d6a817e39d3bae0f47dbc09838d51db22a5d30.tar.bz2
coreclr-61d6a817e39d3bae0f47dbc09838d51db22a5d30.zip
Imported Upstream version 2.0.0.11992upstream/2.0.0.11992
Diffstat (limited to 'src/pal')
-rw-r--r--src/pal/inc/pal.h8
-rw-r--r--src/pal/prebuilt/idl/corprof_i.cpp9
-rw-r--r--src/pal/prebuilt/inc/corprof.h804
-rw-r--r--src/pal/src/CMakeLists.txt4
-rw-r--r--src/pal/src/config.h.in3
-rw-r--r--src/pal/src/configure.cmake20
-rw-r--r--src/pal/src/file/file.cpp6
-rw-r--r--src/pal/src/include/pal/context.h10
-rw-r--r--src/pal/src/include/pal/virtual.h20
-rw-r--r--src/pal/src/map/map.cpp21
-rw-r--r--src/pal/src/map/virtual.cpp229
-rw-r--r--src/pal/src/synchmgr/synchmanager.cpp12
-rw-r--r--src/pal/src/thread/process.cpp4
-rw-r--r--src/pal/src/thread/threadsusp.cpp12
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/MapViewOfFile/test1/MapViewOfFile.cpp26
-rw-r--r--src/pal/tests/palsuite/paltestlist.txt1
-rwxr-xr-xsrc/pal/tools/gen-buildsys-clang.sh2
17 files changed, 1124 insertions, 67 deletions
diff --git a/src/pal/inc/pal.h b/src/pal/inc/pal.h
index 35c9a51f43..0f470d9668 100644
--- a/src/pal/inc/pal.h
+++ b/src/pal/inc/pal.h
@@ -2853,6 +2853,14 @@ PAL_GetSymbolModuleBase(void *symbol);
PALIMPORT
LPVOID
PALAPI
+PAL_VirtualReserveFromExecutableMemoryAllocatorWithinRange(
+ IN LPCVOID lpBeginAddress,
+ IN LPCVOID lpEndAddress,
+ IN SIZE_T dwSize);
+
+PALIMPORT
+LPVOID
+PALAPI
VirtualAlloc(
IN LPVOID lpAddress,
IN SIZE_T dwSize,
diff --git a/src/pal/prebuilt/idl/corprof_i.cpp b/src/pal/prebuilt/idl/corprof_i.cpp
index 3758da041c..090f84452c 100644
--- a/src/pal/prebuilt/idl/corprof_i.cpp
+++ b/src/pal/prebuilt/idl/corprof_i.cpp
@@ -7,7 +7,7 @@
/* link this file in with the server and any clients */
- /* File created by MIDL compiler version 8.00.0603 */
+ /* File created by MIDL compiler version 8.01.0622 */
/* @@MIDL_FILE_HEADING( ) */
#pragma warning( disable: 4049 ) /* more than 64k source lines */
@@ -55,9 +55,9 @@ typedef IID CLSID;
#endif // CLSID_DEFINED
#define MIDL_DEFINE_GUID(type,name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) \
- const type name = {l,w1,w2,{b1,b2,b3,b4,b5,b6,b7,b8}}
+ EXTERN_C __declspec(selectany) const type name = {l,w1,w2,{b1,b2,b3,b4,b5,b6,b7,b8}}
-#endif !_MIDL_USE_GUIDDEF_
+#endif // !_MIDL_USE_GUIDDEF_
MIDL_DEFINE_GUID(IID, IID_ICorProfilerCallback,0x176FBED1,0xA55C,0x4796,0x98,0xCA,0xA9,0xDA,0x0E,0xF8,0x83,0xE7);
@@ -83,6 +83,9 @@ MIDL_DEFINE_GUID(IID, IID_ICorProfilerCallback7,0xF76A2DBA,0x1D52,0x4539,0x86,0x
MIDL_DEFINE_GUID(IID, IID_ICorProfilerCallback8,0x5BED9B15,0xC079,0x4D47,0xBF,0xE2,0x21,0x5A,0x14,0x0C,0x07,0xE0);
+MIDL_DEFINE_GUID(IID, IID_ICorProfilerCallback9,0x27583EC3,0xC8F5,0x482F,0x80,0x52,0x19,0x4B,0x8C,0xE4,0x70,0x5A);
+
+
MIDL_DEFINE_GUID(IID, IID_ICorProfilerInfo,0x28B5557D,0x3F3F,0x48b4,0x90,0xB2,0x5F,0x9E,0xEA,0x2F,0x6C,0x48);
diff --git a/src/pal/prebuilt/inc/corprof.h b/src/pal/prebuilt/inc/corprof.h
index 6778fb526f..befa45a942 100644
--- a/src/pal/prebuilt/inc/corprof.h
+++ b/src/pal/prebuilt/inc/corprof.h
@@ -5,7 +5,7 @@
/* this ALWAYS GENERATED file contains the definitions for the interfaces */
- /* File created by MIDL compiler version 8.01.0620 */
+ /* File created by MIDL compiler version 8.01.0622 */
/* @@MIDL_FILE_HEADING( ) */
#pragma warning( disable: 4049 ) /* more than 64k source lines */
@@ -93,6 +93,13 @@ typedef interface ICorProfilerCallback8 ICorProfilerCallback8;
#endif /* __ICorProfilerCallback8_FWD_DEFINED__ */
+#ifndef __ICorProfilerCallback9_FWD_DEFINED__
+#define __ICorProfilerCallback9_FWD_DEFINED__
+typedef interface ICorProfilerCallback9 ICorProfilerCallback9;
+
+#endif /* __ICorProfilerCallback9_FWD_DEFINED__ */
+
+
#ifndef __ICorProfilerInfo_FWD_DEFINED__
#define __ICorProfilerInfo_FWD_DEFINED__
typedef interface ICorProfilerInfo ICorProfilerInfo;
@@ -506,8 +513,9 @@ enum __MIDL___MIDL_itf_corprof_0000_0000_0006
COR_PRF_HIGH_MONITOR_NONE = 0,
COR_PRF_HIGH_ADD_ASSEMBLY_REFERENCES = 0x1,
COR_PRF_HIGH_IN_MEMORY_SYMBOLS_UPDATED = 0x2,
+ COR_PRF_HIGH_MONITOR_DYNAMIC_FUNCTION_UNLOADS = 0x4,
COR_PRF_HIGH_REQUIRE_PROFILE_IMAGE = 0,
- COR_PRF_HIGH_ALLOWABLE_AFTER_ATTACH = COR_PRF_HIGH_IN_MEMORY_SYMBOLS_UPDATED,
+ COR_PRF_HIGH_ALLOWABLE_AFTER_ATTACH = ( COR_PRF_HIGH_IN_MEMORY_SYMBOLS_UPDATED | COR_PRF_HIGH_MONITOR_DYNAMIC_FUNCTION_UNLOADS ) ,
COR_PRF_HIGH_MONITOR_IMMUTABLE = 0
} COR_PRF_HIGH_MONITOR;
@@ -6611,11 +6619,795 @@ EXTERN_C const IID IID_ICorProfilerCallback8;
#endif /* __ICorProfilerCallback8_INTERFACE_DEFINED__ */
-/* interface __MIDL_itf_corprof_0000_0008 */
+#ifndef __ICorProfilerCallback9_INTERFACE_DEFINED__
+#define __ICorProfilerCallback9_INTERFACE_DEFINED__
+
+/* interface ICorProfilerCallback9 */
+/* [local][unique][uuid][object] */
+
+
+EXTERN_C const IID IID_ICorProfilerCallback9;
+
+#if defined(__cplusplus) && !defined(CINTERFACE)
+
+ MIDL_INTERFACE("27583EC3-C8F5-482F-8052-194B8CE4705A")
+ ICorProfilerCallback9 : public ICorProfilerCallback8
+ {
+ public:
+ virtual HRESULT STDMETHODCALLTYPE DynamicMethodUnloaded(
+ /* [in] */ FunctionID functionId) = 0;
+
+ };
+
+
+#else /* C style interface */
+
+ typedef struct ICorProfilerCallback9Vtbl
+ {
+ BEGIN_INTERFACE
+
+ HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
+ ICorProfilerCallback9 * This,
+ /* [in] */ REFIID riid,
+ /* [annotation][iid_is][out] */
+ _COM_Outptr_ void **ppvObject);
+
+ ULONG ( STDMETHODCALLTYPE *AddRef )(
+ ICorProfilerCallback9 * This);
+
+ ULONG ( STDMETHODCALLTYPE *Release )(
+ ICorProfilerCallback9 * This);
+
+ HRESULT ( STDMETHODCALLTYPE *Initialize )(
+ ICorProfilerCallback9 * This,
+ /* [in] */ IUnknown *pICorProfilerInfoUnk);
+
+ HRESULT ( STDMETHODCALLTYPE *Shutdown )(
+ ICorProfilerCallback9 * This);
+
+ HRESULT ( STDMETHODCALLTYPE *AppDomainCreationStarted )(
+ ICorProfilerCallback9 * This,
+ /* [in] */ AppDomainID appDomainId);
+
+ HRESULT ( STDMETHODCALLTYPE *AppDomainCreationFinished )(
+ ICorProfilerCallback9 * This,
+ /* [in] */ AppDomainID appDomainId,
+ /* [in] */ HRESULT hrStatus);
+
+ HRESULT ( STDMETHODCALLTYPE *AppDomainShutdownStarted )(
+ ICorProfilerCallback9 * This,
+ /* [in] */ AppDomainID appDomainId);
+
+ HRESULT ( STDMETHODCALLTYPE *AppDomainShutdownFinished )(
+ ICorProfilerCallback9 * This,
+ /* [in] */ AppDomainID appDomainId,
+ /* [in] */ HRESULT hrStatus);
+
+ HRESULT ( STDMETHODCALLTYPE *AssemblyLoadStarted )(
+ ICorProfilerCallback9 * This,
+ /* [in] */ AssemblyID assemblyId);
+
+ HRESULT ( STDMETHODCALLTYPE *AssemblyLoadFinished )(
+ ICorProfilerCallback9 * This,
+ /* [in] */ AssemblyID assemblyId,
+ /* [in] */ HRESULT hrStatus);
+
+ HRESULT ( STDMETHODCALLTYPE *AssemblyUnloadStarted )(
+ ICorProfilerCallback9 * This,
+ /* [in] */ AssemblyID assemblyId);
+
+ HRESULT ( STDMETHODCALLTYPE *AssemblyUnloadFinished )(
+ ICorProfilerCallback9 * This,
+ /* [in] */ AssemblyID assemblyId,
+ /* [in] */ HRESULT hrStatus);
+
+ HRESULT ( STDMETHODCALLTYPE *ModuleLoadStarted )(
+ ICorProfilerCallback9 * This,
+ /* [in] */ ModuleID moduleId);
+
+ HRESULT ( STDMETHODCALLTYPE *ModuleLoadFinished )(
+ ICorProfilerCallback9 * This,
+ /* [in] */ ModuleID moduleId,
+ /* [in] */ HRESULT hrStatus);
+
+ HRESULT ( STDMETHODCALLTYPE *ModuleUnloadStarted )(
+ ICorProfilerCallback9 * This,
+ /* [in] */ ModuleID moduleId);
+
+ HRESULT ( STDMETHODCALLTYPE *ModuleUnloadFinished )(
+ ICorProfilerCallback9 * This,
+ /* [in] */ ModuleID moduleId,
+ /* [in] */ HRESULT hrStatus);
+
+ HRESULT ( STDMETHODCALLTYPE *ModuleAttachedToAssembly )(
+ ICorProfilerCallback9 * This,
+ /* [in] */ ModuleID moduleId,
+ /* [in] */ AssemblyID AssemblyId);
+
+ HRESULT ( STDMETHODCALLTYPE *ClassLoadStarted )(
+ ICorProfilerCallback9 * This,
+ /* [in] */ ClassID classId);
+
+ HRESULT ( STDMETHODCALLTYPE *ClassLoadFinished )(
+ ICorProfilerCallback9 * This,
+ /* [in] */ ClassID classId,
+ /* [in] */ HRESULT hrStatus);
+
+ HRESULT ( STDMETHODCALLTYPE *ClassUnloadStarted )(
+ ICorProfilerCallback9 * This,
+ /* [in] */ ClassID classId);
+
+ HRESULT ( STDMETHODCALLTYPE *ClassUnloadFinished )(
+ ICorProfilerCallback9 * This,
+ /* [in] */ ClassID classId,
+ /* [in] */ HRESULT hrStatus);
+
+ HRESULT ( STDMETHODCALLTYPE *FunctionUnloadStarted )(
+ ICorProfilerCallback9 * This,
+ /* [in] */ FunctionID functionId);
+
+ HRESULT ( STDMETHODCALLTYPE *JITCompilationStarted )(
+ ICorProfilerCallback9 * This,
+ /* [in] */ FunctionID functionId,
+ /* [in] */ BOOL fIsSafeToBlock);
+
+ HRESULT ( STDMETHODCALLTYPE *JITCompilationFinished )(
+ ICorProfilerCallback9 * This,
+ /* [in] */ FunctionID functionId,
+ /* [in] */ HRESULT hrStatus,
+ /* [in] */ BOOL fIsSafeToBlock);
+
+ HRESULT ( STDMETHODCALLTYPE *JITCachedFunctionSearchStarted )(
+ ICorProfilerCallback9 * This,
+ /* [in] */ FunctionID functionId,
+ /* [out] */ BOOL *pbUseCachedFunction);
+
+ HRESULT ( STDMETHODCALLTYPE *JITCachedFunctionSearchFinished )(
+ ICorProfilerCallback9 * This,
+ /* [in] */ FunctionID functionId,
+ /* [in] */ COR_PRF_JIT_CACHE result);
+
+ HRESULT ( STDMETHODCALLTYPE *JITFunctionPitched )(
+ ICorProfilerCallback9 * This,
+ /* [in] */ FunctionID functionId);
+
+ HRESULT ( STDMETHODCALLTYPE *JITInlining )(
+ ICorProfilerCallback9 * This,
+ /* [in] */ FunctionID callerId,
+ /* [in] */ FunctionID calleeId,
+ /* [out] */ BOOL *pfShouldInline);
+
+ HRESULT ( STDMETHODCALLTYPE *ThreadCreated )(
+ ICorProfilerCallback9 * This,
+ /* [in] */ ThreadID threadId);
+
+ HRESULT ( STDMETHODCALLTYPE *ThreadDestroyed )(
+ ICorProfilerCallback9 * This,
+ /* [in] */ ThreadID threadId);
+
+ HRESULT ( STDMETHODCALLTYPE *ThreadAssignedToOSThread )(
+ ICorProfilerCallback9 * This,
+ /* [in] */ ThreadID managedThreadId,
+ /* [in] */ DWORD osThreadId);
+
+ HRESULT ( STDMETHODCALLTYPE *RemotingClientInvocationStarted )(
+ ICorProfilerCallback9 * This);
+
+ HRESULT ( STDMETHODCALLTYPE *RemotingClientSendingMessage )(
+ ICorProfilerCallback9 * This,
+ /* [in] */ GUID *pCookie,
+ /* [in] */ BOOL fIsAsync);
+
+ HRESULT ( STDMETHODCALLTYPE *RemotingClientReceivingReply )(
+ ICorProfilerCallback9 * This,
+ /* [in] */ GUID *pCookie,
+ /* [in] */ BOOL fIsAsync);
+
+ HRESULT ( STDMETHODCALLTYPE *RemotingClientInvocationFinished )(
+ ICorProfilerCallback9 * This);
+
+ HRESULT ( STDMETHODCALLTYPE *RemotingServerReceivingMessage )(
+ ICorProfilerCallback9 * This,
+ /* [in] */ GUID *pCookie,
+ /* [in] */ BOOL fIsAsync);
+
+ HRESULT ( STDMETHODCALLTYPE *RemotingServerInvocationStarted )(
+ ICorProfilerCallback9 * This);
+
+ HRESULT ( STDMETHODCALLTYPE *RemotingServerInvocationReturned )(
+ ICorProfilerCallback9 * This);
+
+ HRESULT ( STDMETHODCALLTYPE *RemotingServerSendingReply )(
+ ICorProfilerCallback9 * This,
+ /* [in] */ GUID *pCookie,
+ /* [in] */ BOOL fIsAsync);
+
+ HRESULT ( STDMETHODCALLTYPE *UnmanagedToManagedTransition )(
+ ICorProfilerCallback9 * This,
+ /* [in] */ FunctionID functionId,
+ /* [in] */ COR_PRF_TRANSITION_REASON reason);
+
+ HRESULT ( STDMETHODCALLTYPE *ManagedToUnmanagedTransition )(
+ ICorProfilerCallback9 * This,
+ /* [in] */ FunctionID functionId,
+ /* [in] */ COR_PRF_TRANSITION_REASON reason);
+
+ HRESULT ( STDMETHODCALLTYPE *RuntimeSuspendStarted )(
+ ICorProfilerCallback9 * This,
+ /* [in] */ COR_PRF_SUSPEND_REASON suspendReason);
+
+ HRESULT ( STDMETHODCALLTYPE *RuntimeSuspendFinished )(
+ ICorProfilerCallback9 * This);
+
+ HRESULT ( STDMETHODCALLTYPE *RuntimeSuspendAborted )(
+ ICorProfilerCallback9 * This);
+
+ HRESULT ( STDMETHODCALLTYPE *RuntimeResumeStarted )(
+ ICorProfilerCallback9 * This);
+
+ HRESULT ( STDMETHODCALLTYPE *RuntimeResumeFinished )(
+ ICorProfilerCallback9 * This);
+
+ HRESULT ( STDMETHODCALLTYPE *RuntimeThreadSuspended )(
+ ICorProfilerCallback9 * This,
+ /* [in] */ ThreadID threadId);
+
+ HRESULT ( STDMETHODCALLTYPE *RuntimeThreadResumed )(
+ ICorProfilerCallback9 * This,
+ /* [in] */ ThreadID threadId);
+
+ HRESULT ( STDMETHODCALLTYPE *MovedReferences )(
+ ICorProfilerCallback9 * This,
+ /* [in] */ ULONG cMovedObjectIDRanges,
+ /* [size_is][in] */ ObjectID oldObjectIDRangeStart[ ],
+ /* [size_is][in] */ ObjectID newObjectIDRangeStart[ ],
+ /* [size_is][in] */ ULONG cObjectIDRangeLength[ ]);
+
+ HRESULT ( STDMETHODCALLTYPE *ObjectAllocated )(
+ ICorProfilerCallback9 * This,
+ /* [in] */ ObjectID objectId,
+ /* [in] */ ClassID classId);
+
+ HRESULT ( STDMETHODCALLTYPE *ObjectsAllocatedByClass )(
+ ICorProfilerCallback9 * This,
+ /* [in] */ ULONG cClassCount,
+ /* [size_is][in] */ ClassID classIds[ ],
+ /* [size_is][in] */ ULONG cObjects[ ]);
+
+ HRESULT ( STDMETHODCALLTYPE *ObjectReferences )(
+ ICorProfilerCallback9 * This,
+ /* [in] */ ObjectID objectId,
+ /* [in] */ ClassID classId,
+ /* [in] */ ULONG cObjectRefs,
+ /* [size_is][in] */ ObjectID objectRefIds[ ]);
+
+ HRESULT ( STDMETHODCALLTYPE *RootReferences )(
+ ICorProfilerCallback9 * This,
+ /* [in] */ ULONG cRootRefs,
+ /* [size_is][in] */ ObjectID rootRefIds[ ]);
+
+ HRESULT ( STDMETHODCALLTYPE *ExceptionThrown )(
+ ICorProfilerCallback9 * This,
+ /* [in] */ ObjectID thrownObjectId);
+
+ HRESULT ( STDMETHODCALLTYPE *ExceptionSearchFunctionEnter )(
+ ICorProfilerCallback9 * This,
+ /* [in] */ FunctionID functionId);
+
+ HRESULT ( STDMETHODCALLTYPE *ExceptionSearchFunctionLeave )(
+ ICorProfilerCallback9 * This);
+
+ HRESULT ( STDMETHODCALLTYPE *ExceptionSearchFilterEnter )(
+ ICorProfilerCallback9 * This,
+ /* [in] */ FunctionID functionId);
+
+ HRESULT ( STDMETHODCALLTYPE *ExceptionSearchFilterLeave )(
+ ICorProfilerCallback9 * This);
+
+ HRESULT ( STDMETHODCALLTYPE *ExceptionSearchCatcherFound )(
+ ICorProfilerCallback9 * This,
+ /* [in] */ FunctionID functionId);
+
+ HRESULT ( STDMETHODCALLTYPE *ExceptionOSHandlerEnter )(
+ ICorProfilerCallback9 * This,
+ /* [in] */ UINT_PTR __unused);
+
+ HRESULT ( STDMETHODCALLTYPE *ExceptionOSHandlerLeave )(
+ ICorProfilerCallback9 * This,
+ /* [in] */ UINT_PTR __unused);
+
+ HRESULT ( STDMETHODCALLTYPE *ExceptionUnwindFunctionEnter )(
+ ICorProfilerCallback9 * This,
+ /* [in] */ FunctionID functionId);
+
+ HRESULT ( STDMETHODCALLTYPE *ExceptionUnwindFunctionLeave )(
+ ICorProfilerCallback9 * This);
+
+ HRESULT ( STDMETHODCALLTYPE *ExceptionUnwindFinallyEnter )(
+ ICorProfilerCallback9 * This,
+ /* [in] */ FunctionID functionId);
+
+ HRESULT ( STDMETHODCALLTYPE *ExceptionUnwindFinallyLeave )(
+ ICorProfilerCallback9 * This);
+
+ HRESULT ( STDMETHODCALLTYPE *ExceptionCatcherEnter )(
+ ICorProfilerCallback9 * This,
+ /* [in] */ FunctionID functionId,
+ /* [in] */ ObjectID objectId);
+
+ HRESULT ( STDMETHODCALLTYPE *ExceptionCatcherLeave )(
+ ICorProfilerCallback9 * This);
+
+ HRESULT ( STDMETHODCALLTYPE *COMClassicVTableCreated )(
+ ICorProfilerCallback9 * This,
+ /* [in] */ ClassID wrappedClassId,
+ /* [in] */ REFGUID implementedIID,
+ /* [in] */ void *pVTable,
+ /* [in] */ ULONG cSlots);
+
+ HRESULT ( STDMETHODCALLTYPE *COMClassicVTableDestroyed )(
+ ICorProfilerCallback9 * This,
+ /* [in] */ ClassID wrappedClassId,
+ /* [in] */ REFGUID implementedIID,
+ /* [in] */ void *pVTable);
+
+ HRESULT ( STDMETHODCALLTYPE *ExceptionCLRCatcherFound )(
+ ICorProfilerCallback9 * This);
+
+ HRESULT ( STDMETHODCALLTYPE *ExceptionCLRCatcherExecute )(
+ ICorProfilerCallback9 * This);
+
+ HRESULT ( STDMETHODCALLTYPE *ThreadNameChanged )(
+ ICorProfilerCallback9 * This,
+ /* [in] */ ThreadID threadId,
+ /* [in] */ ULONG cchName,
+ /* [annotation][in] */
+ _In_reads_opt_(cchName) WCHAR name[ ]);
+
+ HRESULT ( STDMETHODCALLTYPE *GarbageCollectionStarted )(
+ ICorProfilerCallback9 * This,
+ /* [in] */ int cGenerations,
+ /* [size_is][in] */ BOOL generationCollected[ ],
+ /* [in] */ COR_PRF_GC_REASON reason);
+
+ HRESULT ( STDMETHODCALLTYPE *SurvivingReferences )(
+ ICorProfilerCallback9 * This,
+ /* [in] */ ULONG cSurvivingObjectIDRanges,
+ /* [size_is][in] */ ObjectID objectIDRangeStart[ ],
+ /* [size_is][in] */ ULONG cObjectIDRangeLength[ ]);
+
+ HRESULT ( STDMETHODCALLTYPE *GarbageCollectionFinished )(
+ ICorProfilerCallback9 * This);
+
+ HRESULT ( STDMETHODCALLTYPE *FinalizeableObjectQueued )(
+ ICorProfilerCallback9 * This,
+ /* [in] */ DWORD finalizerFlags,
+ /* [in] */ ObjectID objectID);
+
+ HRESULT ( STDMETHODCALLTYPE *RootReferences2 )(
+ ICorProfilerCallback9 * This,
+ /* [in] */ ULONG cRootRefs,
+ /* [size_is][in] */ ObjectID rootRefIds[ ],
+ /* [size_is][in] */ COR_PRF_GC_ROOT_KIND rootKinds[ ],
+ /* [size_is][in] */ COR_PRF_GC_ROOT_FLAGS rootFlags[ ],
+ /* [size_is][in] */ UINT_PTR rootIds[ ]);
+
+ HRESULT ( STDMETHODCALLTYPE *HandleCreated )(
+ ICorProfilerCallback9 * This,
+ /* [in] */ GCHandleID handleId,
+ /* [in] */ ObjectID initialObjectId);
+
+ HRESULT ( STDMETHODCALLTYPE *HandleDestroyed )(
+ ICorProfilerCallback9 * This,
+ /* [in] */ GCHandleID handleId);
+
+ HRESULT ( STDMETHODCALLTYPE *InitializeForAttach )(
+ ICorProfilerCallback9 * This,
+ /* [in] */ IUnknown *pCorProfilerInfoUnk,
+ /* [in] */ void *pvClientData,
+ /* [in] */ UINT cbClientData);
+
+ HRESULT ( STDMETHODCALLTYPE *ProfilerAttachComplete )(
+ ICorProfilerCallback9 * This);
+
+ HRESULT ( STDMETHODCALLTYPE *ProfilerDetachSucceeded )(
+ ICorProfilerCallback9 * This);
+
+ HRESULT ( STDMETHODCALLTYPE *ReJITCompilationStarted )(
+ ICorProfilerCallback9 * This,
+ /* [in] */ FunctionID functionId,
+ /* [in] */ ReJITID rejitId,
+ /* [in] */ BOOL fIsSafeToBlock);
+
+ HRESULT ( STDMETHODCALLTYPE *GetReJITParameters )(
+ ICorProfilerCallback9 * This,
+ /* [in] */ ModuleID moduleId,
+ /* [in] */ mdMethodDef methodId,
+ /* [in] */ ICorProfilerFunctionControl *pFunctionControl);
+
+ HRESULT ( STDMETHODCALLTYPE *ReJITCompilationFinished )(
+ ICorProfilerCallback9 * This,
+ /* [in] */ FunctionID functionId,
+ /* [in] */ ReJITID rejitId,
+ /* [in] */ HRESULT hrStatus,
+ /* [in] */ BOOL fIsSafeToBlock);
+
+ HRESULT ( STDMETHODCALLTYPE *ReJITError )(
+ ICorProfilerCallback9 * This,
+ /* [in] */ ModuleID moduleId,
+ /* [in] */ mdMethodDef methodId,
+ /* [in] */ FunctionID functionId,
+ /* [in] */ HRESULT hrStatus);
+
+ HRESULT ( STDMETHODCALLTYPE *MovedReferences2 )(
+ ICorProfilerCallback9 * This,
+ /* [in] */ ULONG cMovedObjectIDRanges,
+ /* [size_is][in] */ ObjectID oldObjectIDRangeStart[ ],
+ /* [size_is][in] */ ObjectID newObjectIDRangeStart[ ],
+ /* [size_is][in] */ SIZE_T cObjectIDRangeLength[ ]);
+
+ HRESULT ( STDMETHODCALLTYPE *SurvivingReferences2 )(
+ ICorProfilerCallback9 * This,
+ /* [in] */ ULONG cSurvivingObjectIDRanges,
+ /* [size_is][in] */ ObjectID objectIDRangeStart[ ],
+ /* [size_is][in] */ SIZE_T cObjectIDRangeLength[ ]);
+
+ HRESULT ( STDMETHODCALLTYPE *ConditionalWeakTableElementReferences )(
+ ICorProfilerCallback9 * This,
+ /* [in] */ ULONG cRootRefs,
+ /* [size_is][in] */ ObjectID keyRefIds[ ],
+ /* [size_is][in] */ ObjectID valueRefIds[ ],
+ /* [size_is][in] */ GCHandleID rootIds[ ]);
+
+ HRESULT ( STDMETHODCALLTYPE *GetAssemblyReferences )(
+ ICorProfilerCallback9 * This,
+ /* [string][in] */ const WCHAR *wszAssemblyPath,
+ /* [in] */ ICorProfilerAssemblyReferenceProvider *pAsmRefProvider);
+
+ HRESULT ( STDMETHODCALLTYPE *ModuleInMemorySymbolsUpdated )(
+ ICorProfilerCallback9 * This,
+ ModuleID moduleId);
+
+ HRESULT ( STDMETHODCALLTYPE *DynamicMethodJITCompilationStarted )(
+ ICorProfilerCallback9 * This,
+ /* [in] */ FunctionID functionId,
+ /* [in] */ BOOL fIsSafeToBlock,
+ /* [in] */ LPCBYTE pILHeader,
+ /* [in] */ ULONG cbILHeader);
+
+ HRESULT ( STDMETHODCALLTYPE *DynamicMethodJITCompilationFinished )(
+ ICorProfilerCallback9 * This,
+ /* [in] */ FunctionID functionId,
+ /* [in] */ HRESULT hrStatus,
+ /* [in] */ BOOL fIsSafeToBlock);
+
+ HRESULT ( STDMETHODCALLTYPE *DynamicMethodUnloaded )(
+ ICorProfilerCallback9 * This,
+ /* [in] */ FunctionID functionId);
+
+ END_INTERFACE
+ } ICorProfilerCallback9Vtbl;
+
+ interface ICorProfilerCallback9
+ {
+ CONST_VTBL struct ICorProfilerCallback9Vtbl *lpVtbl;
+ };
+
+
+
+#ifdef COBJMACROS
+
+
+#define ICorProfilerCallback9_QueryInterface(This,riid,ppvObject) \
+ ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
+
+#define ICorProfilerCallback9_AddRef(This) \
+ ( (This)->lpVtbl -> AddRef(This) )
+
+#define ICorProfilerCallback9_Release(This) \
+ ( (This)->lpVtbl -> Release(This) )
+
+
+#define ICorProfilerCallback9_Initialize(This,pICorProfilerInfoUnk) \
+ ( (This)->lpVtbl -> Initialize(This,pICorProfilerInfoUnk) )
+
+#define ICorProfilerCallback9_Shutdown(This) \
+ ( (This)->lpVtbl -> Shutdown(This) )
+
+#define ICorProfilerCallback9_AppDomainCreationStarted(This,appDomainId) \
+ ( (This)->lpVtbl -> AppDomainCreationStarted(This,appDomainId) )
+
+#define ICorProfilerCallback9_AppDomainCreationFinished(This,appDomainId,hrStatus) \
+ ( (This)->lpVtbl -> AppDomainCreationFinished(This,appDomainId,hrStatus) )
+
+#define ICorProfilerCallback9_AppDomainShutdownStarted(This,appDomainId) \
+ ( (This)->lpVtbl -> AppDomainShutdownStarted(This,appDomainId) )
+
+#define ICorProfilerCallback9_AppDomainShutdownFinished(This,appDomainId,hrStatus) \
+ ( (This)->lpVtbl -> AppDomainShutdownFinished(This,appDomainId,hrStatus) )
+
+#define ICorProfilerCallback9_AssemblyLoadStarted(This,assemblyId) \
+ ( (This)->lpVtbl -> AssemblyLoadStarted(This,assemblyId) )
+
+#define ICorProfilerCallback9_AssemblyLoadFinished(This,assemblyId,hrStatus) \
+ ( (This)->lpVtbl -> AssemblyLoadFinished(This,assemblyId,hrStatus) )
+
+#define ICorProfilerCallback9_AssemblyUnloadStarted(This,assemblyId) \
+ ( (This)->lpVtbl -> AssemblyUnloadStarted(This,assemblyId) )
+
+#define ICorProfilerCallback9_AssemblyUnloadFinished(This,assemblyId,hrStatus) \
+ ( (This)->lpVtbl -> AssemblyUnloadFinished(This,assemblyId,hrStatus) )
+
+#define ICorProfilerCallback9_ModuleLoadStarted(This,moduleId) \
+ ( (This)->lpVtbl -> ModuleLoadStarted(This,moduleId) )
+
+#define ICorProfilerCallback9_ModuleLoadFinished(This,moduleId,hrStatus) \
+ ( (This)->lpVtbl -> ModuleLoadFinished(This,moduleId,hrStatus) )
+
+#define ICorProfilerCallback9_ModuleUnloadStarted(This,moduleId) \
+ ( (This)->lpVtbl -> ModuleUnloadStarted(This,moduleId) )
+
+#define ICorProfilerCallback9_ModuleUnloadFinished(This,moduleId,hrStatus) \
+ ( (This)->lpVtbl -> ModuleUnloadFinished(This,moduleId,hrStatus) )
+
+#define ICorProfilerCallback9_ModuleAttachedToAssembly(This,moduleId,AssemblyId) \
+ ( (This)->lpVtbl -> ModuleAttachedToAssembly(This,moduleId,AssemblyId) )
+
+#define ICorProfilerCallback9_ClassLoadStarted(This,classId) \
+ ( (This)->lpVtbl -> ClassLoadStarted(This,classId) )
+
+#define ICorProfilerCallback9_ClassLoadFinished(This,classId,hrStatus) \
+ ( (This)->lpVtbl -> ClassLoadFinished(This,classId,hrStatus) )
+
+#define ICorProfilerCallback9_ClassUnloadStarted(This,classId) \
+ ( (This)->lpVtbl -> ClassUnloadStarted(This,classId) )
+
+#define ICorProfilerCallback9_ClassUnloadFinished(This,classId,hrStatus) \
+ ( (This)->lpVtbl -> ClassUnloadFinished(This,classId,hrStatus) )
+
+#define ICorProfilerCallback9_FunctionUnloadStarted(This,functionId) \
+ ( (This)->lpVtbl -> FunctionUnloadStarted(This,functionId) )
+
+#define ICorProfilerCallback9_JITCompilationStarted(This,functionId,fIsSafeToBlock) \
+ ( (This)->lpVtbl -> JITCompilationStarted(This,functionId,fIsSafeToBlock) )
+
+#define ICorProfilerCallback9_JITCompilationFinished(This,functionId,hrStatus,fIsSafeToBlock) \
+ ( (This)->lpVtbl -> JITCompilationFinished(This,functionId,hrStatus,fIsSafeToBlock) )
+
+#define ICorProfilerCallback9_JITCachedFunctionSearchStarted(This,functionId,pbUseCachedFunction) \
+ ( (This)->lpVtbl -> JITCachedFunctionSearchStarted(This,functionId,pbUseCachedFunction) )
+
+#define ICorProfilerCallback9_JITCachedFunctionSearchFinished(This,functionId,result) \
+ ( (This)->lpVtbl -> JITCachedFunctionSearchFinished(This,functionId,result) )
+
+#define ICorProfilerCallback9_JITFunctionPitched(This,functionId) \
+ ( (This)->lpVtbl -> JITFunctionPitched(This,functionId) )
+
+#define ICorProfilerCallback9_JITInlining(This,callerId,calleeId,pfShouldInline) \
+ ( (This)->lpVtbl -> JITInlining(This,callerId,calleeId,pfShouldInline) )
+
+#define ICorProfilerCallback9_ThreadCreated(This,threadId) \
+ ( (This)->lpVtbl -> ThreadCreated(This,threadId) )
+
+#define ICorProfilerCallback9_ThreadDestroyed(This,threadId) \
+ ( (This)->lpVtbl -> ThreadDestroyed(This,threadId) )
+
+#define ICorProfilerCallback9_ThreadAssignedToOSThread(This,managedThreadId,osThreadId) \
+ ( (This)->lpVtbl -> ThreadAssignedToOSThread(This,managedThreadId,osThreadId) )
+
+#define ICorProfilerCallback9_RemotingClientInvocationStarted(This) \
+ ( (This)->lpVtbl -> RemotingClientInvocationStarted(This) )
+
+#define ICorProfilerCallback9_RemotingClientSendingMessage(This,pCookie,fIsAsync) \
+ ( (This)->lpVtbl -> RemotingClientSendingMessage(This,pCookie,fIsAsync) )
+
+#define ICorProfilerCallback9_RemotingClientReceivingReply(This,pCookie,fIsAsync) \
+ ( (This)->lpVtbl -> RemotingClientReceivingReply(This,pCookie,fIsAsync) )
+
+#define ICorProfilerCallback9_RemotingClientInvocationFinished(This) \
+ ( (This)->lpVtbl -> RemotingClientInvocationFinished(This) )
+
+#define ICorProfilerCallback9_RemotingServerReceivingMessage(This,pCookie,fIsAsync) \
+ ( (This)->lpVtbl -> RemotingServerReceivingMessage(This,pCookie,fIsAsync) )
+
+#define ICorProfilerCallback9_RemotingServerInvocationStarted(This) \
+ ( (This)->lpVtbl -> RemotingServerInvocationStarted(This) )
+
+#define ICorProfilerCallback9_RemotingServerInvocationReturned(This) \
+ ( (This)->lpVtbl -> RemotingServerInvocationReturned(This) )
+
+#define ICorProfilerCallback9_RemotingServerSendingReply(This,pCookie,fIsAsync) \
+ ( (This)->lpVtbl -> RemotingServerSendingReply(This,pCookie,fIsAsync) )
+
+#define ICorProfilerCallback9_UnmanagedToManagedTransition(This,functionId,reason) \
+ ( (This)->lpVtbl -> UnmanagedToManagedTransition(This,functionId,reason) )
+
+#define ICorProfilerCallback9_ManagedToUnmanagedTransition(This,functionId,reason) \
+ ( (This)->lpVtbl -> ManagedToUnmanagedTransition(This,functionId,reason) )
+
+#define ICorProfilerCallback9_RuntimeSuspendStarted(This,suspendReason) \
+ ( (This)->lpVtbl -> RuntimeSuspendStarted(This,suspendReason) )
+
+#define ICorProfilerCallback9_RuntimeSuspendFinished(This) \
+ ( (This)->lpVtbl -> RuntimeSuspendFinished(This) )
+
+#define ICorProfilerCallback9_RuntimeSuspendAborted(This) \
+ ( (This)->lpVtbl -> RuntimeSuspendAborted(This) )
+
+#define ICorProfilerCallback9_RuntimeResumeStarted(This) \
+ ( (This)->lpVtbl -> RuntimeResumeStarted(This) )
+
+#define ICorProfilerCallback9_RuntimeResumeFinished(This) \
+ ( (This)->lpVtbl -> RuntimeResumeFinished(This) )
+
+#define ICorProfilerCallback9_RuntimeThreadSuspended(This,threadId) \
+ ( (This)->lpVtbl -> RuntimeThreadSuspended(This,threadId) )
+
+#define ICorProfilerCallback9_RuntimeThreadResumed(This,threadId) \
+ ( (This)->lpVtbl -> RuntimeThreadResumed(This,threadId) )
+
+#define ICorProfilerCallback9_MovedReferences(This,cMovedObjectIDRanges,oldObjectIDRangeStart,newObjectIDRangeStart,cObjectIDRangeLength) \
+ ( (This)->lpVtbl -> MovedReferences(This,cMovedObjectIDRanges,oldObjectIDRangeStart,newObjectIDRangeStart,cObjectIDRangeLength) )
+
+#define ICorProfilerCallback9_ObjectAllocated(This,objectId,classId) \
+ ( (This)->lpVtbl -> ObjectAllocated(This,objectId,classId) )
+
+#define ICorProfilerCallback9_ObjectsAllocatedByClass(This,cClassCount,classIds,cObjects) \
+ ( (This)->lpVtbl -> ObjectsAllocatedByClass(This,cClassCount,classIds,cObjects) )
+
+#define ICorProfilerCallback9_ObjectReferences(This,objectId,classId,cObjectRefs,objectRefIds) \
+ ( (This)->lpVtbl -> ObjectReferences(This,objectId,classId,cObjectRefs,objectRefIds) )
+
+#define ICorProfilerCallback9_RootReferences(This,cRootRefs,rootRefIds) \
+ ( (This)->lpVtbl -> RootReferences(This,cRootRefs,rootRefIds) )
+
+#define ICorProfilerCallback9_ExceptionThrown(This,thrownObjectId) \
+ ( (This)->lpVtbl -> ExceptionThrown(This,thrownObjectId) )
+
+#define ICorProfilerCallback9_ExceptionSearchFunctionEnter(This,functionId) \
+ ( (This)->lpVtbl -> ExceptionSearchFunctionEnter(This,functionId) )
+
+#define ICorProfilerCallback9_ExceptionSearchFunctionLeave(This) \
+ ( (This)->lpVtbl -> ExceptionSearchFunctionLeave(This) )
+
+#define ICorProfilerCallback9_ExceptionSearchFilterEnter(This,functionId) \
+ ( (This)->lpVtbl -> ExceptionSearchFilterEnter(This,functionId) )
+
+#define ICorProfilerCallback9_ExceptionSearchFilterLeave(This) \
+ ( (This)->lpVtbl -> ExceptionSearchFilterLeave(This) )
+
+#define ICorProfilerCallback9_ExceptionSearchCatcherFound(This,functionId) \
+ ( (This)->lpVtbl -> ExceptionSearchCatcherFound(This,functionId) )
+
+#define ICorProfilerCallback9_ExceptionOSHandlerEnter(This,__unused) \
+ ( (This)->lpVtbl -> ExceptionOSHandlerEnter(This,__unused) )
+
+#define ICorProfilerCallback9_ExceptionOSHandlerLeave(This,__unused) \
+ ( (This)->lpVtbl -> ExceptionOSHandlerLeave(This,__unused) )
+
+#define ICorProfilerCallback9_ExceptionUnwindFunctionEnter(This,functionId) \
+ ( (This)->lpVtbl -> ExceptionUnwindFunctionEnter(This,functionId) )
+
+#define ICorProfilerCallback9_ExceptionUnwindFunctionLeave(This) \
+ ( (This)->lpVtbl -> ExceptionUnwindFunctionLeave(This) )
+
+#define ICorProfilerCallback9_ExceptionUnwindFinallyEnter(This,functionId) \
+ ( (This)->lpVtbl -> ExceptionUnwindFinallyEnter(This,functionId) )
+
+#define ICorProfilerCallback9_ExceptionUnwindFinallyLeave(This) \
+ ( (This)->lpVtbl -> ExceptionUnwindFinallyLeave(This) )
+
+#define ICorProfilerCallback9_ExceptionCatcherEnter(This,functionId,objectId) \
+ ( (This)->lpVtbl -> ExceptionCatcherEnter(This,functionId,objectId) )
+
+#define ICorProfilerCallback9_ExceptionCatcherLeave(This) \
+ ( (This)->lpVtbl -> ExceptionCatcherLeave(This) )
+
+#define ICorProfilerCallback9_COMClassicVTableCreated(This,wrappedClassId,implementedIID,pVTable,cSlots) \
+ ( (This)->lpVtbl -> COMClassicVTableCreated(This,wrappedClassId,implementedIID,pVTable,cSlots) )
+
+#define ICorProfilerCallback9_COMClassicVTableDestroyed(This,wrappedClassId,implementedIID,pVTable) \
+ ( (This)->lpVtbl -> COMClassicVTableDestroyed(This,wrappedClassId,implementedIID,pVTable) )
+
+#define ICorProfilerCallback9_ExceptionCLRCatcherFound(This) \
+ ( (This)->lpVtbl -> ExceptionCLRCatcherFound(This) )
+
+#define ICorProfilerCallback9_ExceptionCLRCatcherExecute(This) \
+ ( (This)->lpVtbl -> ExceptionCLRCatcherExecute(This) )
+
+
+#define ICorProfilerCallback9_ThreadNameChanged(This,threadId,cchName,name) \
+ ( (This)->lpVtbl -> ThreadNameChanged(This,threadId,cchName,name) )
+
+#define ICorProfilerCallback9_GarbageCollectionStarted(This,cGenerations,generationCollected,reason) \
+ ( (This)->lpVtbl -> GarbageCollectionStarted(This,cGenerations,generationCollected,reason) )
+
+#define ICorProfilerCallback9_SurvivingReferences(This,cSurvivingObjectIDRanges,objectIDRangeStart,cObjectIDRangeLength) \
+ ( (This)->lpVtbl -> SurvivingReferences(This,cSurvivingObjectIDRanges,objectIDRangeStart,cObjectIDRangeLength) )
+
+#define ICorProfilerCallback9_GarbageCollectionFinished(This) \
+ ( (This)->lpVtbl -> GarbageCollectionFinished(This) )
+
+#define ICorProfilerCallback9_FinalizeableObjectQueued(This,finalizerFlags,objectID) \
+ ( (This)->lpVtbl -> FinalizeableObjectQueued(This,finalizerFlags,objectID) )
+
+#define ICorProfilerCallback9_RootReferences2(This,cRootRefs,rootRefIds,rootKinds,rootFlags,rootIds) \
+ ( (This)->lpVtbl -> RootReferences2(This,cRootRefs,rootRefIds,rootKinds,rootFlags,rootIds) )
+
+#define ICorProfilerCallback9_HandleCreated(This,handleId,initialObjectId) \
+ ( (This)->lpVtbl -> HandleCreated(This,handleId,initialObjectId) )
+
+#define ICorProfilerCallback9_HandleDestroyed(This,handleId) \
+ ( (This)->lpVtbl -> HandleDestroyed(This,handleId) )
+
+
+#define ICorProfilerCallback9_InitializeForAttach(This,pCorProfilerInfoUnk,pvClientData,cbClientData) \
+ ( (This)->lpVtbl -> InitializeForAttach(This,pCorProfilerInfoUnk,pvClientData,cbClientData) )
+
+#define ICorProfilerCallback9_ProfilerAttachComplete(This) \
+ ( (This)->lpVtbl -> ProfilerAttachComplete(This) )
+
+#define ICorProfilerCallback9_ProfilerDetachSucceeded(This) \
+ ( (This)->lpVtbl -> ProfilerDetachSucceeded(This) )
+
+
+#define ICorProfilerCallback9_ReJITCompilationStarted(This,functionId,rejitId,fIsSafeToBlock) \
+ ( (This)->lpVtbl -> ReJITCompilationStarted(This,functionId,rejitId,fIsSafeToBlock) )
+
+#define ICorProfilerCallback9_GetReJITParameters(This,moduleId,methodId,pFunctionControl) \
+ ( (This)->lpVtbl -> GetReJITParameters(This,moduleId,methodId,pFunctionControl) )
+
+#define ICorProfilerCallback9_ReJITCompilationFinished(This,functionId,rejitId,hrStatus,fIsSafeToBlock) \
+ ( (This)->lpVtbl -> ReJITCompilationFinished(This,functionId,rejitId,hrStatus,fIsSafeToBlock) )
+
+#define ICorProfilerCallback9_ReJITError(This,moduleId,methodId,functionId,hrStatus) \
+ ( (This)->lpVtbl -> ReJITError(This,moduleId,methodId,functionId,hrStatus) )
+
+#define ICorProfilerCallback9_MovedReferences2(This,cMovedObjectIDRanges,oldObjectIDRangeStart,newObjectIDRangeStart,cObjectIDRangeLength) \
+ ( (This)->lpVtbl -> MovedReferences2(This,cMovedObjectIDRanges,oldObjectIDRangeStart,newObjectIDRangeStart,cObjectIDRangeLength) )
+
+#define ICorProfilerCallback9_SurvivingReferences2(This,cSurvivingObjectIDRanges,objectIDRangeStart,cObjectIDRangeLength) \
+ ( (This)->lpVtbl -> SurvivingReferences2(This,cSurvivingObjectIDRanges,objectIDRangeStart,cObjectIDRangeLength) )
+
+
+#define ICorProfilerCallback9_ConditionalWeakTableElementReferences(This,cRootRefs,keyRefIds,valueRefIds,rootIds) \
+ ( (This)->lpVtbl -> ConditionalWeakTableElementReferences(This,cRootRefs,keyRefIds,valueRefIds,rootIds) )
+
+
+#define ICorProfilerCallback9_GetAssemblyReferences(This,wszAssemblyPath,pAsmRefProvider) \
+ ( (This)->lpVtbl -> GetAssemblyReferences(This,wszAssemblyPath,pAsmRefProvider) )
+
+
+#define ICorProfilerCallback9_ModuleInMemorySymbolsUpdated(This,moduleId) \
+ ( (This)->lpVtbl -> ModuleInMemorySymbolsUpdated(This,moduleId) )
+
+
+#define ICorProfilerCallback9_DynamicMethodJITCompilationStarted(This,functionId,fIsSafeToBlock,pILHeader,cbILHeader) \
+ ( (This)->lpVtbl -> DynamicMethodJITCompilationStarted(This,functionId,fIsSafeToBlock,pILHeader,cbILHeader) )
+
+#define ICorProfilerCallback9_DynamicMethodJITCompilationFinished(This,functionId,hrStatus,fIsSafeToBlock) \
+ ( (This)->lpVtbl -> DynamicMethodJITCompilationFinished(This,functionId,hrStatus,fIsSafeToBlock) )
+
+
+#define ICorProfilerCallback9_DynamicMethodUnloaded(This,functionId) \
+ ( (This)->lpVtbl -> DynamicMethodUnloaded(This,functionId) )
+
+#endif /* COBJMACROS */
+
+
+#endif /* C style interface */
+
+
+
+
+#endif /* __ICorProfilerCallback9_INTERFACE_DEFINED__ */
+
+
+/* interface __MIDL_itf_corprof_0000_0009 */
/* [local] */
typedef /* [public] */
-enum __MIDL___MIDL_itf_corprof_0000_0008_0001
+enum __MIDL___MIDL_itf_corprof_0000_0009_0001
{
COR_PRF_CODEGEN_DISABLE_INLINING = 0x1,
COR_PRF_CODEGEN_DISABLE_ALL_OPTIMIZATIONS = 0x2
@@ -6623,8 +7415,8 @@ enum __MIDL___MIDL_itf_corprof_0000_0008_0001
-extern RPC_IF_HANDLE __MIDL_itf_corprof_0000_0008_v0_0_c_ifspec;
-extern RPC_IF_HANDLE __MIDL_itf_corprof_0000_0008_v0_0_s_ifspec;
+extern RPC_IF_HANDLE __MIDL_itf_corprof_0000_0009_v0_0_c_ifspec;
+extern RPC_IF_HANDLE __MIDL_itf_corprof_0000_0009_v0_0_s_ifspec;
#ifndef __ICorProfilerInfo_INTERFACE_DEFINED__
#define __ICorProfilerInfo_INTERFACE_DEFINED__
diff --git a/src/pal/src/CMakeLists.txt b/src/pal/src/CMakeLists.txt
index 145c2c9ed9..b8a9fe9e46 100644
--- a/src/pal/src/CMakeLists.txt
+++ b/src/pal/src/CMakeLists.txt
@@ -93,10 +93,10 @@ elseif(PAL_CMAKE_PLATFORM_ARCH_I386)
set(PAL_ARCH_SOURCES_DIR i386)
endif()
-if(CMAKE_SYSTEM_NAME STREQUAL Linux AND NOT CLR_CMAKE_PLATFORM_ALPINE_LINUX)
+if(PAL_CMAKE_PLATFORM_ARCH_AMD64 AND CMAKE_SYSTEM_NAME STREQUAL Linux AND NOT CLR_CMAKE_PLATFORM_ALPINE_LINUX)
# Currently the _xstate is not available on Alpine Linux
add_definitions(-DXSTATE_SUPPORTED)
-endif(CMAKE_SYSTEM_NAME STREQUAL Linux AND NOT CLR_CMAKE_PLATFORM_ALPINE_LINUX)
+endif(PAL_CMAKE_PLATFORM_ARCH_AMD64 AND CMAKE_SYSTEM_NAME STREQUAL Linux AND NOT CLR_CMAKE_PLATFORM_ALPINE_LINUX)
if(CLR_CMAKE_PLATFORM_ALPINE_LINUX)
# Setting RLIMIT_NOFILE breaks debugging of coreclr on Alpine Linux for some reason
diff --git a/src/pal/src/config.h.in b/src/pal/src/config.h.in
index 7f37f42222..03513a1264 100644
--- a/src/pal/src/config.h.in
+++ b/src/pal/src/config.h.in
@@ -61,11 +61,14 @@
#cmakedefine01 HAS_SYSV_SEMAPHORES
#cmakedefine01 HAS_PTHREAD_MUTEXES
#cmakedefine01 HAVE_TTRACE
+#cmakedefine01 HAVE_PIPE2
#cmakedefine01 HAVE_SCHED_GETAFFINITY
#cmakedefine HAVE_UNW_GET_SAVE_LOC
#cmakedefine HAVE_UNW_GET_ACCESSORS
#cmakedefine01 HAVE_XSWDEV
#cmakedefine01 HAVE_XSW_USAGE
+#cmakedefine01 HAVE_PUBLIC_XSTATE_STRUCT
+#cmakedefine01 HAVE_PR_SET_PTRACER
#cmakedefine01 HAVE_STAT_TIMESPEC
#cmakedefine01 HAVE_STAT_NSEC
diff --git a/src/pal/src/configure.cmake b/src/pal/src/configure.cmake
index b5b98d5b2d..2f17f6b08c 100644
--- a/src/pal/src/configure.cmake
+++ b/src/pal/src/configure.cmake
@@ -99,6 +99,7 @@ check_function_exists(directio HAVE_DIRECTIO)
check_function_exists(semget HAS_SYSV_SEMAPHORES)
check_function_exists(pthread_mutex_init HAS_PTHREAD_MUTEXES)
check_function_exists(ttrace HAVE_TTRACE)
+check_function_exists(pipe2 HAVE_PIPE2)
set(CMAKE_REQUIRED_LIBRARIES unwind unwind-generic)
check_cxx_source_compiles("
#include <libunwind.h>
@@ -1022,6 +1023,25 @@ int main(int argc, char **argv)
return 0;
}" HAVE_XSW_USAGE)
+check_cxx_source_compiles("
+#include <signal.h>
+
+int main(int argc, char **argv)
+{
+ struct _xstate xstate;
+ struct _fpx_sw_bytes bytes;
+ return 0;
+}" HAVE_PUBLIC_XSTATE_STRUCT)
+
+check_cxx_source_compiles("
+#include <sys/prctl.h>
+
+int main(int argc, char **argv)
+{
+ int flag = (int)PR_SET_PTRACER;
+ return 0;
+}" HAVE_PR_SET_PTRACER)
+
set(CMAKE_REQUIRED_LIBRARIES pthread)
check_cxx_source_compiles("
#include <errno.h>
diff --git a/src/pal/src/file/file.cpp b/src/pal/src/file/file.cpp
index a4ad20db32..feec65531c 100644
--- a/src/pal/src/file/file.cpp
+++ b/src/pal/src/file/file.cpp
@@ -4056,14 +4056,14 @@ CorUnix::InternalCreatePipe(
/* enable close-on-exec for both pipes; if one gets passed to CreateProcess
it will be "uncloseonexeced" in order to be inherited */
- if(-1 == fcntl(readWritePipeDes[0],F_SETFD,1))
+ if(-1 == fcntl(readWritePipeDes[0],F_SETFD,FD_CLOEXEC))
{
ASSERT("can't set close-on-exec flag; fcntl() failed. errno is %d "
"(%s)\n", errno, strerror(errno));
palError = ERROR_INTERNAL_ERROR;
goto InternalCreatePipeExit;
}
- if(-1 == fcntl(readWritePipeDes[1],F_SETFD,1))
+ if(-1 == fcntl(readWritePipeDes[1],F_SETFD,FD_CLOEXEC))
{
ASSERT("can't set close-on-exec flag; fcntl() failed. errno is %d "
"(%s)\n", errno, strerror(errno));
@@ -4564,7 +4564,7 @@ static HANDLE init_std_handle(HANDLE * pStd, FILE *stream)
/* duplicate the FILE *, so that we can fclose() in FILECloseHandle without
closing the original */
- new_fd = dup(fileno(stream));
+ new_fd = fcntl(fileno(stream), F_DUPFD_CLOEXEC, 0); // dup, but with CLOEXEC
if(-1 == new_fd)
{
ERROR("dup() failed; errno is %d (%s)\n", errno, strerror(errno));
diff --git a/src/pal/src/include/pal/context.h b/src/pal/src/include/pal/context.h
index db6d69579a..2c86a03d69 100644
--- a/src/pal/src/include/pal/context.h
+++ b/src/pal/src/include/pal/context.h
@@ -39,6 +39,16 @@ typedef ucontext_t native_context_t;
#else // HAVE_UCONTEXT_T
#error Native context type is not known on this platform!
#endif // HAVE_UCONTEXT_T
+
+#if defined(XSTATE_SUPPORTED) && !HAVE_PUBLIC_XSTATE_STRUCT
+namespace asm_sigcontext
+{
+#include <asm/sigcontext.h>
+};
+using asm_sigcontext::_fpx_sw_bytes;
+using asm_sigcontext::_xstate;
+#endif // defined(XSTATE_SUPPORTED) && !HAVE_PUBLIC_XSTATE_STRUCT
+
#else // !HAVE_MACH_EXCEPTIONS
#include <mach/kern_return.h>
#include <mach/mach_port.h>
diff --git a/src/pal/src/include/pal/virtual.h b/src/pal/src/include/pal/virtual.h
index 31d225fc04..36eaf81e3a 100644
--- a/src/pal/src/include/pal/virtual.h
+++ b/src/pal/src/include/pal/virtual.h
@@ -60,7 +60,7 @@ enum VIRTUAL_CONSTANTS
VIRTUAL_PAGE_SIZE = 0x1000,
VIRTUAL_PAGE_MASK = VIRTUAL_PAGE_SIZE - 1,
- BOUNDARY_64K = 0xffff
+ VIRTUAL_64KB = 0x10000
};
/*++
@@ -130,11 +130,22 @@ public:
AllocateMemory
This function attempts to allocate the requested amount of memory from its reserved virtual
- address space. The function will return NULL if the allocation request cannot
+ address space. The function will return null if the allocation request cannot
be satisfied by the memory that is currently available in the allocator.
--*/
void* AllocateMemory(SIZE_T allocationSize);
+ /*++
+ Function:
+ AllocateMemory
+
+ This function attempts to allocate the requested amount of memory from its reserved virtual
+ address space, if memory is available within the specified range. The function will return
+ null if the allocation request cannot satisfied by the memory that is currently available in
+ the allocator.
+ --*/
+ void *AllocateMemoryWithinRange(const void *beginAddress, const void *endAddress, SIZE_T allocationSize);
+
private:
/*++
Function:
@@ -160,12 +171,13 @@ private:
// that can be used to calculate an approximate location of the memory that
// is in 2GB range from the coreclr library. In addition, having precise size of libcoreclr
// is not necessary for the calculations.
- const int32_t CoreClrLibrarySize = 100 * 1024 * 1024;
+ static const int32_t CoreClrLibrarySize = 100 * 1024 * 1024;
// This constant represent the max size of the virtual memory that this allocator
// will try to reserve during initialization. We want all JIT-ed code and the
// entire libcoreclr to be located in a 2GB range.
- const int32_t MaxExecutableMemorySize = 0x7FFF0000 - CoreClrLibrarySize;
+ static const int32_t MaxExecutableMemorySize = 0x7FFF0000;
+ static const int32_t MaxExecutableMemorySizeNearCoreClr = MaxExecutableMemorySize - CoreClrLibrarySize;
// Start address of the reserved virtual address space
void* m_startAddress;
diff --git a/src/pal/src/map/map.cpp b/src/pal/src/map/map.cpp
index 5fdb6fda38..b8ffc84db4 100644
--- a/src/pal/src/map/map.cpp
+++ b/src/pal/src/map/map.cpp
@@ -246,7 +246,7 @@ FileMappingInitializationRoutine(
pProcessLocalData->UnixFd = InternalOpen(
pImmutableData->szFileName,
- MAPProtectionToFileOpenFlags(pImmutableData->flProtect)
+ MAPProtectionToFileOpenFlags(pImmutableData->flProtect) | O_CLOEXEC
);
if (-1 == pProcessLocalData->UnixFd)
@@ -510,7 +510,7 @@ CorUnix::InternalCreateFileMapping(
#if HAVE_MMAP_DEV_ZERO
- UnixFd = InternalOpen(pImmutableData->szFileName, O_RDWR);
+ UnixFd = InternalOpen(pImmutableData->szFileName, O_RDWR | O_CLOEXEC);
if ( -1 == UnixFd )
{
ERROR( "Unable to open the file.\n");
@@ -587,7 +587,7 @@ CorUnix::InternalCreateFileMapping(
// information, though...
//
- UnixFd = dup(pFileLocalData->unix_fd);
+ UnixFd = fcntl(pFileLocalData->unix_fd, F_DUPFD_CLOEXEC, 0); // dup, but with CLOEXEC
if (-1 == UnixFd)
{
ERROR( "Unable to duplicate the Unix file descriptor!\n" );
@@ -2440,20 +2440,21 @@ void * MAPMapPEFile(HANDLE hFile)
// We're going to start adding mappings to the mapping list, so take the critical section
InternalEnterCriticalSection(pThread, &mapping_critsec);
-#if !defined(_AMD64_)
- loadedBase = mmap((void*)preferredBase, virtualSize, PROT_NONE, MAP_ANON|MAP_PRIVATE, -1, 0);
-#else // defined(_AMD64_)
+#ifdef BIT64
// First try to reserve virtual memory using ExecutableAllcator. This allows all PE images to be
// near each other and close to the coreclr library which also allows the runtime to generate
- // more efficient code (by avoiding usage of jump stubs).
- loadedBase = ReserveMemoryFromExecutableAllocator(pThread, ALIGN_UP(virtualSize, GetVirtualPageSize()));
+ // more efficient code (by avoiding usage of jump stubs). Alignment to a 64 KB granularity should
+ // not be necessary (alignment to page size should be sufficient), but see
+ // ExecutableMemoryAllocator::AllocateMemory() for the reason why it is done.
+ loadedBase = ReserveMemoryFromExecutableAllocator(pThread, ALIGN_UP(virtualSize, VIRTUAL_64KB));
+#endif // BIT64
+
if (loadedBase == NULL)
{
// MAC64 requires we pass MAP_SHARED (or MAP_PRIVATE) flags - otherwise, the call is failed.
// Refer to mmap documentation at http://www.manpagez.com/man/2/mmap/ for details.
- loadedBase = mmap((void*)preferredBase, virtualSize, PROT_NONE, MAP_ANON|MAP_PRIVATE, -1, 0);
+ loadedBase = mmap(NULL, virtualSize, PROT_NONE, MAP_ANON|MAP_PRIVATE, -1, 0);
}
-#endif // !defined(_AMD64_)
if (MAP_FAILED == loadedBase)
{
diff --git a/src/pal/src/map/virtual.cpp b/src/pal/src/map/virtual.cpp
index 7e00843b7a..41bd37c9b4 100644
--- a/src/pal/src/map/virtual.cpp
+++ b/src/pal/src/map/virtual.cpp
@@ -18,15 +18,19 @@ Abstract:
--*/
+#include "pal/dbgmsg.h"
+
+SET_DEFAULT_DEBUG_CHANNEL(VIRTUAL); // some headers have code with asserts, so do this first
+
#include "pal/thread.hpp"
#include "pal/cs.hpp"
#include "pal/malloc.hpp"
#include "pal/file.hpp"
#include "pal/seh.hpp"
-#include "pal/dbgmsg.h"
#include "pal/virtual.h"
#include "pal/map.h"
#include "pal/init.h"
+#include "pal/utils.h"
#include "common.h"
#include <sys/types.h>
@@ -43,8 +47,6 @@ Abstract:
using namespace CorUnix;
-SET_DEFAULT_DEBUG_CHANNEL(VIRTUAL);
-
CRITICAL_SECTION virtual_critsec;
// The first node in our list of allocated blocks.
@@ -93,6 +95,7 @@ namespace VirtualMemoryLogging
Decommit = 0x40,
Release = 0x50,
Reset = 0x60,
+ ReserveFromExecutableMemoryAllocatorWithinRange = 0x70
};
// Indicates that the attempted operation has failed
@@ -884,8 +887,13 @@ static LPVOID VIRTUALReserveMemory(
// First, figure out where we're trying to reserve the memory and
// how much we need. On most systems, requests to mmap must be
- // page-aligned and at multiples of the page size.
- StartBoundary = (UINT_PTR)lpAddress & ~BOUNDARY_64K;
+ // page-aligned and at multiples of the page size. Unlike on Windows, on
+ // Unix, the allocation granularity is the page size, so the memory size to
+ // reserve is not aligned to 64 KB. Nor should the start boundary need to
+ // to be aligned down to 64 KB, but it is expected that there are other
+ // components that rely on this alignment when providing a specific address
+ // (note that mmap itself does not make any such guarantees).
+ StartBoundary = (UINT_PTR)ALIGN_DOWN(lpAddress, VIRTUAL_64KB);
/* Add the sizes, and round down to the nearest page boundary. */
MemSize = ( ((UINT_PTR)lpAddress + dwSize + VIRTUAL_PAGE_MASK) & ~VIRTUAL_PAGE_MASK ) -
StartBoundary;
@@ -894,7 +902,14 @@ static LPVOID VIRTUALReserveMemory(
// try to get memory from the executable memory allocator to satisfy the request.
if (((flAllocationType & MEM_RESERVE_EXECUTABLE) != 0) && (lpAddress == NULL))
{
- pRetVal = g_executableMemoryAllocator.AllocateMemory(MemSize);
+ // Alignment to a 64 KB granularity should not be necessary (alignment to page size should be sufficient), but see
+ // ExecutableMemoryAllocator::AllocateMemory() for the reason why it is done
+ SIZE_T reservationSize = ALIGN_UP(MemSize, VIRTUAL_64KB);
+ pRetVal = g_executableMemoryAllocator.AllocateMemory(reservationSize);
+ if (pRetVal != nullptr)
+ {
+ MemSize = reservationSize;
+ }
}
if (pRetVal == NULL)
@@ -1227,6 +1242,72 @@ done:
/*++
Function:
+ PAL_VirtualReserveFromExecutableMemoryAllocatorWithinRange
+
+ This function attempts to allocate the requested amount of memory in the specified address range, from the executable memory
+ allocator. If unable to do so, the function returns nullptr and does not set the last error.
+
+ lpBeginAddress - Inclusive beginning of range
+ lpEndAddress - Exclusive end of range
+ dwSize - Number of bytes to allocate
+--*/
+LPVOID
+PALAPI
+PAL_VirtualReserveFromExecutableMemoryAllocatorWithinRange(
+ IN LPCVOID lpBeginAddress,
+ IN LPCVOID lpEndAddress,
+ IN SIZE_T dwSize)
+{
+#ifdef BIT64
+ PERF_ENTRY(PAL_VirtualReserveFromExecutableMemoryAllocatorWithinRange);
+ ENTRY(
+ "PAL_VirtualReserveFromExecutableMemoryAllocatorWithinRange(lpBeginAddress = %p, lpEndAddress = %p, dwSize = %Iu)\n",
+ lpBeginAddress,
+ lpEndAddress,
+ dwSize);
+
+ _ASSERTE(lpBeginAddress <= lpEndAddress);
+
+ // Alignment to a 64 KB granularity should not be necessary (alignment to page size should be sufficient), but see
+ // ExecutableMemoryAllocator::AllocateMemory() for the reason why it is done
+ SIZE_T reservationSize = ALIGN_UP(dwSize, VIRTUAL_64KB);
+
+ CPalThread *currentThread = InternalGetCurrentThread();
+ InternalEnterCriticalSection(currentThread, &virtual_critsec);
+
+ void *address = g_executableMemoryAllocator.AllocateMemoryWithinRange(lpBeginAddress, lpEndAddress, reservationSize);
+ if (address != nullptr)
+ {
+ _ASSERTE(IS_ALIGNED(address, VIRTUAL_PAGE_SIZE));
+ if (!VIRTUALStoreAllocationInfo((UINT_PTR)address, reservationSize, MEM_RESERVE | MEM_RESERVE_EXECUTABLE, PAGE_NOACCESS))
+ {
+ ASSERT("Unable to store the structure in the list.\n");
+ munmap(address, reservationSize);
+ address = nullptr;
+ }
+ }
+
+ LogVaOperation(
+ VirtualMemoryLogging::VirtualOperation::ReserveFromExecutableMemoryAllocatorWithinRange,
+ nullptr,
+ dwSize,
+ MEM_RESERVE | MEM_RESERVE_EXECUTABLE,
+ PAGE_NOACCESS,
+ address,
+ TRUE);
+
+ InternalLeaveCriticalSection(currentThread, &virtual_critsec);
+
+ LOGEXIT("PAL_VirtualReserveFromExecutableMemoryAllocatorWithinRange returning %p\n", address);
+ PERF_EXIT(PAL_VirtualReserveFromExecutableMemoryAllocatorWithinRange);
+ return address;
+#else // !BIT64
+ return nullptr;
+#endif // BIT64
+}
+
+/*++
+Function:
VirtualAlloc
Note:
@@ -1982,11 +2063,15 @@ Function :
--*/
void* ReserveMemoryFromExecutableAllocator(CPalThread* pThread, SIZE_T allocationSize)
{
+#ifdef BIT64
InternalEnterCriticalSection(pThread, &virtual_critsec);
void* mem = g_executableMemoryAllocator.AllocateMemory(allocationSize);
InternalLeaveCriticalSection(pThread, &virtual_critsec);
return mem;
+#else // !BIT64
+ return nullptr;
+#endif // BIT64
}
/*++
@@ -2024,14 +2109,14 @@ Function:
void ExecutableMemoryAllocator::TryReserveInitialMemory()
{
CPalThread* pthrCurrent = InternalGetCurrentThread();
- int32_t sizeOfAllocation = MaxExecutableMemorySize;
- int32_t startAddressIncrement;
- UINT_PTR startAddress;
+ int32_t sizeOfAllocation = MaxExecutableMemorySizeNearCoreClr;
+ int32_t preferredStartAddressIncrement;
+ UINT_PTR preferredStartAddress;
UINT_PTR coreclrLoadAddress;
const int32_t MemoryProbingIncrement = 128 * 1024 * 1024;
// Try to find and reserve an available region of virtual memory that is located
- // within 2GB range (defined by the MaxExecutableMemorySize constant) from the
+ // within 2GB range (defined by the MaxExecutableMemorySizeNearCoreClr constant) from the
// location of the coreclr library.
// Potentially, as a possible future improvement, we can get precise information
// about available memory ranges by parsing data from '/proc/self/maps'.
@@ -2045,40 +2130,69 @@ void ExecutableMemoryAllocator::TryReserveInitialMemory()
// (thus avoiding reserving memory below 4GB; besides some operating systems do not allow that).
// If libcoreclr is loaded at high addresses then try to reserve memory below its location.
coreclrLoadAddress = (UINT_PTR)PAL_GetSymbolModuleBase((void*)VirtualAlloc);
- if ((coreclrLoadAddress < 0xFFFFFFFF) || ((coreclrLoadAddress - MaxExecutableMemorySize) < 0xFFFFFFFF))
+ if ((coreclrLoadAddress < 0xFFFFFFFF) || ((coreclrLoadAddress - MaxExecutableMemorySizeNearCoreClr) < 0xFFFFFFFF))
{
// Try to allocate above the location of libcoreclr
- startAddress = coreclrLoadAddress + CoreClrLibrarySize;
- startAddressIncrement = MemoryProbingIncrement;
+ preferredStartAddress = coreclrLoadAddress + CoreClrLibrarySize;
+ preferredStartAddressIncrement = MemoryProbingIncrement;
}
else
{
// Try to allocate below the location of libcoreclr
- startAddress = coreclrLoadAddress - MaxExecutableMemorySize;
- startAddressIncrement = 0;
+ preferredStartAddress = coreclrLoadAddress - MaxExecutableMemorySizeNearCoreClr;
+ preferredStartAddressIncrement = 0;
}
// Do actual memory reservation.
do
{
- m_startAddress = ReserveVirtualMemory(pthrCurrent, (void*)startAddress, sizeOfAllocation);
- if (m_startAddress != NULL)
+ m_startAddress = ReserveVirtualMemory(pthrCurrent, (void*)preferredStartAddress, sizeOfAllocation);
+ if (m_startAddress != nullptr)
{
- // Memory has been successfully reserved.
- m_totalSizeOfReservedMemory = sizeOfAllocation;
-
- // Randomize the location at which we start allocating from the reserved memory range.
- int32_t randomOffset = GenerateRandomStartOffset();
- m_nextFreeAddress = (void*)(((UINT_PTR)m_startAddress) + randomOffset);
- m_remainingReservedMemory = sizeOfAllocation - randomOffset;
break;
}
// Try to allocate a smaller region
sizeOfAllocation -= MemoryProbingIncrement;
- startAddress += startAddressIncrement;
+ preferredStartAddress += preferredStartAddressIncrement;
} while (sizeOfAllocation >= MemoryProbingIncrement);
+
+ if (m_startAddress == nullptr)
+ {
+ // We were not able to reserve any memory near libcoreclr. Try to reserve approximately 2 GB of address space somewhere
+ // anyway:
+ // - This sets aside address space that can be used for executable code, such that jumps/calls between such code may
+ // continue to use short relative addresses instead of long absolute addresses that would currently require jump
+ // stubs.
+ // - The inability to allocate memory in a specific range for jump stubs is an unrecoverable problem. This reservation
+ // would mitigate such issues that can become prevalent depending on which security features are enabled and to what
+ // extent, such as in particular, PaX's RANDMMAP:
+ // - https://en.wikibooks.org/wiki/Grsecurity/Appendix/Grsecurity_and_PaX_Configuration_Options
+ // - Jump stubs for executable code residing in this region can request memory from this allocator
+ // - Native images can be loaded into this address space, including any jump stubs that are required for its helper
+ // table. This satisfies the vast majority of practical cases where the total amount of loaded native image memory
+ // does not exceed approximately 2 GB.
+ // - The code heap allocator for the JIT can allocate from this address space. Beyond this reservation, one can use
+ // the COMPlus_CodeHeapReserveForJumpStubs environment variable to reserve space for jump stubs.
+ sizeOfAllocation = MaxExecutableMemorySize;
+ m_startAddress = ReserveVirtualMemory(pthrCurrent, nullptr, sizeOfAllocation);
+ if (m_startAddress == nullptr)
+ {
+ return;
+ }
+ }
+
+ // Memory has been successfully reserved.
+ m_totalSizeOfReservedMemory = sizeOfAllocation;
+
+ // Randomize the location at which we start allocating from the reserved memory range. Alignment to a 64 KB granularity
+ // should not be necessary, but see AllocateMemory() for the reason why it is done.
+ int32_t randomOffset = GenerateRandomStartOffset();
+ m_nextFreeAddress = ALIGN_UP((void*)(((UINT_PTR)m_startAddress) + randomOffset), VIRTUAL_64KB);
+ _ASSERTE(sizeOfAllocation >= (UINT_PTR)m_nextFreeAddress - (UINT_PTR)m_startAddress);
+ m_remainingReservedMemory =
+ ALIGN_DOWN(sizeOfAllocation - ((UINT_PTR)m_nextFreeAddress - (UINT_PTR)m_startAddress), VIRTUAL_64KB);
}
/*++
@@ -2086,7 +2200,7 @@ Function:
ExecutableMemoryAllocator::AllocateMemory
This function attempts to allocate the requested amount of memory from its reserved virtual
- address space. The function will return NULL if the allocation request cannot
+ address space. The function will return null if the allocation request cannot
be satisfied by the memory that is currently available in the allocator.
Note: This function MUST be called with the virtual_critsec lock held.
@@ -2094,10 +2208,15 @@ Function:
--*/
void* ExecutableMemoryAllocator::AllocateMemory(SIZE_T allocationSize)
{
- void* allocatedMemory = NULL;
+#ifdef BIT64
+ void* allocatedMemory = nullptr;
- // Allocation size must be in multiples of the virtual page size.
- _ASSERTE((allocationSize & VIRTUAL_PAGE_MASK) == 0);
+ // Alignment to a 64 KB granularity should not be necessary (alignment to page size should be sufficient), but
+ // VIRTUALReserveMemory() aligns down the specified address to a 64 KB granularity, and as long as that is necessary, the
+ // reservation size here must be aligned to a 64 KB granularity to guarantee that all returned addresses are also aligned to
+ // a 64 KB granularity. Otherwise, attempting to reserve memory starting from an unaligned address returned by this function
+ // would fail in VIRTUALReserveMemory.
+ _ASSERTE(IS_ALIGNED(allocationSize, VIRTUAL_64KB));
// The code below assumes that the caller owns the virtual_critsec lock.
// So the calculations are not done in thread-safe manner.
@@ -2106,10 +2225,60 @@ void* ExecutableMemoryAllocator::AllocateMemory(SIZE_T allocationSize)
allocatedMemory = m_nextFreeAddress;
m_nextFreeAddress = (void*)(((UINT_PTR)m_nextFreeAddress) + allocationSize);
m_remainingReservedMemory -= allocationSize;
-
}
return allocatedMemory;
+#else // !BIT64
+ return nullptr;
+#endif // BIT64
+}
+
+/*++
+Function:
+ AllocateMemory
+
+ This function attempts to allocate the requested amount of memory from its reserved virtual
+ address space, if memory is available within the specified range. The function will return
+ null if the allocation request cannot satisfied by the memory that is currently available in
+ the allocator.
+
+ Note: This function MUST be called with the virtual_critsec lock held.
+--*/
+void *ExecutableMemoryAllocator::AllocateMemoryWithinRange(const void *beginAddress, const void *endAddress, SIZE_T allocationSize)
+{
+#ifdef BIT64
+ _ASSERTE(beginAddress <= endAddress);
+
+ // Alignment to a 64 KB granularity should not be necessary (alignment to page size should be sufficient), but see
+ // AllocateMemory() for the reason why it is necessary
+ _ASSERTE(IS_ALIGNED(allocationSize, VIRTUAL_64KB));
+
+ // The code below assumes that the caller owns the virtual_critsec lock.
+ // So the calculations are not done in thread-safe manner.
+
+ if (allocationSize == 0 || allocationSize > m_remainingReservedMemory)
+ {
+ return nullptr;
+ }
+
+ void *address = m_nextFreeAddress;
+ if (address < beginAddress)
+ {
+ return nullptr;
+ }
+
+ void *nextFreeAddress = (void *)((UINT_PTR)address + allocationSize);
+ if (nextFreeAddress > endAddress)
+ {
+ return nullptr;
+ }
+
+ m_nextFreeAddress = nextFreeAddress;
+ m_remainingReservedMemory -= allocationSize;
+ return address;
+#else // !BIT64
+ return nullptr;
+#endif // BIT64
}
/*++
diff --git a/src/pal/src/synchmgr/synchmanager.cpp b/src/pal/src/synchmgr/synchmanager.cpp
index d836a177bb..73b5644dbd 100644
--- a/src/pal/src/synchmgr/synchmanager.cpp
+++ b/src/pal/src/synchmgr/synchmanager.cpp
@@ -3525,12 +3525,22 @@ namespace CorUnix
}
#else // !CORECLR
int rgiPipe[] = { -1, -1 };
- if (pipe(rgiPipe) == -1)
+ int pipeRv =
+#if HAVE_PIPE2
+ pipe2(rgiPipe, O_CLOEXEC);
+#else
+ pipe(rgiPipe);
+#endif // HAVE_PIPE2
+ if (pipeRv == -1)
{
ERROR("Unable to create the process pipe\n");
fRet = false;
goto CPP_exit;
}
+#if !HAVE_PIPE2
+ fcntl(rgiPipe[0], F_SETFD, FD_CLOEXEC); // make pipe non-inheritable, if possible
+ fcntl(rgiPipe[1], F_SETFD, FD_CLOEXEC);
+#endif // !HAVE_PIPE2
#endif // !CORECLR
#if HAVE_KQUEUE && !HAVE_BROKEN_FIFO_KEVENT
diff --git a/src/pal/src/thread/process.cpp b/src/pal/src/thread/process.cpp
index 2a93d3c57d..6db9bf6f51 100644
--- a/src/pal/src/thread/process.cpp
+++ b/src/pal/src/thread/process.cpp
@@ -2981,7 +2981,7 @@ PROCAbort()
// Do any shutdown cleanup before aborting or creating a core dump
PROCNotifyProcessShutdown();
-#if HAVE_PRCTL_H
+#if HAVE_PRCTL_H && HAVE_PR_SET_PTRACER
// If enabled, launch the create minidump utility and wait until it completes
if (g_argvCreateDump[0] != nullptr)
{
@@ -3018,7 +3018,7 @@ PROCAbort()
}
}
}
-#endif // HAVE_PRCTL_H
+#endif // HAVE_PRCTL_H && HAVE_PR_SET_PTRACER
// Abort the process after waiting for the core dump to complete
abort();
}
diff --git a/src/pal/src/thread/threadsusp.cpp b/src/pal/src/thread/threadsusp.cpp
index c7787bef68..f8a435c022 100644
--- a/src/pal/src/thread/threadsusp.cpp
+++ b/src/pal/src/thread/threadsusp.cpp
@@ -74,11 +74,21 @@ CThreadSuspensionInfo::InternalSuspendNewThreadFromData(
ReleaseSuspensionLock(pThread);
int pipe_descs[2];
- if (pipe(pipe_descs) == -1)
+ int pipeRv =
+#if HAVE_PIPE2
+ pipe2(pipe_descs, O_CLOEXEC);
+#else
+ pipe(pipe_descs);
+#endif // HAVE_PIPE2
+ if (pipeRv == -1)
{
ERROR("pipe() failed! error is %d (%s)\n", errno, strerror(errno));
return ERROR_NOT_ENOUGH_MEMORY;
}
+#if !HAVE_PIPE2
+ fcntl(pipe_descs[0], F_SETFD, FD_CLOEXEC); // make pipe non-inheritable, if possible
+ fcntl(pipe_descs[1], F_SETFD, FD_CLOEXEC);
+#endif // !HAVE_PIPE2
// [0] is the read end of the pipe, and [1] is the write end.
pThread->suspensionInfo.SetBlockingPipe(pipe_descs[1]);
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/MapViewOfFile/test1/MapViewOfFile.cpp b/src/pal/tests/palsuite/filemapping_memmgt/MapViewOfFile/test1/MapViewOfFile.cpp
index 6177e0decf..6bfb73f0e8 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/MapViewOfFile/test1/MapViewOfFile.cpp
+++ b/src/pal/tests/palsuite/filemapping_memmgt/MapViewOfFile/test1/MapViewOfFile.cpp
@@ -14,13 +14,26 @@
**============================================================*/
#include <palsuite.h>
#define MAPPINGSIZE 8192
+
+// This test is special - it doesn't work when the file is created on a tmpfs, like the /tmp folder
+// that is the default location for running PAL tests. The reason is that on such filesystem,
+// it is not possible to create file with FILE_FLAG_NO_BUFFERING.
+// So we explicitly use the /var/tmp that cannot be on tmpfs, since it it persistent over reboots.
+
+#ifndef __ANDROID__
+#define TEMP_DIRECTORY_PATH "/var/tmp/"
+#else
+// On Android, "/var/tmp/" doesn't exist; temporary files should go to /data/local/tmp/
+#define TEMP_DIRECTORY_PATH "/data/local/tmp/"
+#endif
+
int __cdecl main(int argc, char *argv[])
{
HANDLE hFile = INVALID_HANDLE_VALUE;
LPSTR buf = NULL;
CHAR ch[MAPPINGSIZE];
- CHAR lpFileName[] = "test.tmp";
+ CHAR lpFilePath[MAX_PATH];
DWORD dwBytesWritten = 0;
DWORD dwInitialSize = 0;
DWORD dwFinalSize = 0;
@@ -36,9 +49,11 @@ int __cdecl main(int argc, char *argv[])
return FAIL;
}
+ GetTempFileName(TEMP_DIRECTORY_PATH, "tst", 0, lpFilePath);
+
/* Create a file handle with CreateFile.
*/
- hFile = CreateFile( lpFileName,
+ hFile = CreateFile( lpFilePath,
GENERIC_WRITE|GENERIC_READ,
FILE_SHARE_READ|FILE_SHARE_WRITE,
NULL,
@@ -49,7 +64,7 @@ int __cdecl main(int argc, char *argv[])
if (hFile == INVALID_HANDLE_VALUE)
{
Fail( "ERROR: %u :unable to create file \"%s\".\n",
- GetLastError(), lpFileName);
+ GetLastError(), lpFilePath);
}
/* Get the initial size of file, for latter tests.
@@ -58,7 +73,7 @@ int __cdecl main(int argc, char *argv[])
if ( INVALID_FILE_SIZE == dwInitialSize )
{
Fail("ERROR:%u: The created file \"%s\" has an invalid "
- "file size.\n",GetLastError(),lpFileName);
+ "file size.\n",GetLastError(),lpFilePath);
}
/*
@@ -220,6 +235,9 @@ int __cdecl main(int argc, char *argv[])
}
VirtualFree( buf, 0, MEM_RELEASE );
+
+ DeleteFile(lpFilePath);
+
PAL_Terminate();
return PASS;
}
diff --git a/src/pal/tests/palsuite/paltestlist.txt b/src/pal/tests/palsuite/paltestlist.txt
index f0dfe3f9ea..1e580cd596 100644
--- a/src/pal/tests/palsuite/paltestlist.txt
+++ b/src/pal/tests/palsuite/paltestlist.txt
@@ -473,6 +473,7 @@ filemapping_memmgt/LocalFree/test1/paltest_localfree_test1
filemapping_memmgt/LocalFree/test2/paltest_localfree_test2
filemapping_memmgt/LockFile/test2/paltest_lockfile_test2
filemapping_memmgt/LockFile/test7/paltest_lockfile_test7
+filemapping_memmgt/MapViewOfFile/test1/paltest_mapviewoffile_test1
filemapping_memmgt/MapViewOfFile/test2/paltest_mapviewoffile_test2
filemapping_memmgt/MapViewOfFile/test3/paltest_mapviewoffile_test3
filemapping_memmgt/MapViewOfFile/test4/paltest_mapviewoffile_test4
diff --git a/src/pal/tools/gen-buildsys-clang.sh b/src/pal/tools/gen-buildsys-clang.sh
index 762a1996b9..944187786f 100755
--- a/src/pal/tools/gen-buildsys-clang.sh
+++ b/src/pal/tools/gen-buildsys-clang.sh
@@ -155,7 +155,7 @@ if [ "$build_arch" == "armel" ]; then
cmake_extra_defines="$cmake_extra_defines -DARM_SOFTFP=1"
fi
-clang_version=$(echo $CC | awk -F- '{ print $NF }')
+clang_version=$( $CC --version | head -1 | sed 's/[^0-9]*\([0-9]*\.[0-9]*\).*/\1/' )
# Use O1 option when the clang version is smaller than 3.9
# Otherwise use O3 option in release build
if [[ ( ${clang_version%.*} -eq 3 && ${clang_version#*.} -lt 9 ) &&