Skip to content
This repository was archived by the owner on Nov 1, 2020. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,10 @@ public static TypeManagerHandle[] Modules
}

[NativeCallable(EntryPoint = "InitializeModules", CallingConvention = CallingConvention.Cdecl)]
internal static void InitializeModules(IntPtr osModule, IntPtr moduleHeaders, int count)
internal static unsafe void InitializeModules(IntPtr osModule, IntPtr moduleHeaders, int count, IntPtr* pClasslibFunctions, int nClasslibFunctions)
{
RuntimeImports.RhpRegisterOsModule(osModule);
TypeManagerHandle[] modules = CreateTypeManagers(osModule, moduleHeaders, count);
TypeManagerHandle[] modules = CreateTypeManagers(osModule, moduleHeaders, count, pClasslibFunctions, nClasslibFunctions);

for (int i = 0; i < modules.Length; i++)
{
Expand All @@ -48,7 +48,7 @@ internal static void InitializeModules(IntPtr osModule, IntPtr moduleHeaders, in
}
}

private static unsafe TypeManagerHandle[] CreateTypeManagers(IntPtr osModule, IntPtr moduleHeaders, int count)
private static unsafe TypeManagerHandle[] CreateTypeManagers(IntPtr osModule, IntPtr moduleHeaders, int count, IntPtr* pClasslibFunctions, int nClasslibFunctions)
{
// Count the number of modules so we can allocate an array to hold the TypeManager objects.
// At this stage of startup, complex collection classes will not work.
Expand All @@ -67,7 +67,7 @@ private static unsafe TypeManagerHandle[] CreateTypeManagers(IntPtr osModule, In
for (int i = 0; i < count; i++)
{
if (((IntPtr*)moduleHeaders)[i] != IntPtr.Zero)
modules[moduleIndex++] = RuntimeImports.RhpCreateTypeManager(osModule, ((IntPtr*)moduleHeaders)[i]);
modules[moduleIndex++] = RuntimeImports.RhpCreateTypeManager(osModule, ((IntPtr*)moduleHeaders)[i], pClasslibFunctions, nClasslibFunctions);
}

return modules;
Expand Down
81 changes: 81 additions & 0 deletions src/Common/src/Interop/Windows/kernel32/Interop.Memory.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System;
using System.Runtime.InteropServices;

internal partial class Interop
{
internal partial class Kernel32
{
[DllImport(Libraries.Kernel32)]
unsafe internal static extern void* VirtualAlloc(void* address, UIntPtr numBytes, int commitOrReserve, int pageProtectionMode);

[DllImport(Libraries.Kernel32)]
unsafe internal static extern bool VirtualFree(void* address, UIntPtr numBytes, int pageFreeMode);

unsafe internal static bool GlobalMemoryStatusEx(ref MEMORYSTATUSEX buffer)
{
buffer.length = sizeof(MEMORYSTATUSEX);
return GlobalMemoryStatusExNative(ref buffer);
}

[DllImport(Libraries.Kernel32, SetLastError = true, EntryPoint = "GlobalMemoryStatusEx")]
private static extern bool GlobalMemoryStatusExNative(ref MEMORYSTATUSEX buffer);

[DllImport(Libraries.Kernel32, SetLastError = true)]
unsafe internal static extern UIntPtr VirtualQuery(void* address, ref MEMORY_BASIC_INFORMATION buffer, UIntPtr sizeOfBuffer);

[DllImport(Libraries.Kernel32, SetLastError = true)]
unsafe internal static extern UIntPtr GetSystemInfo(ref SYSTEM_INFO info);

internal const int MEM_COMMIT = 0x1000;
internal const int MEM_RESERVE = 0x2000;
internal const int MEM_RELEASE = 0x8000;
internal const int MEM_FREE = 0x10000;
internal const int PAGE_READWRITE = 0x04;

[StructLayout(LayoutKind.Sequential)]
internal struct SYSTEM_INFO
{
internal int dwOemId;
internal int dwPageSize;
internal UIntPtr lpMinimumApplicationAddress;
internal UIntPtr lpMaximumApplicationAddress;
internal UIntPtr dwActiveProcessorMask;
internal int dwNumberOfProcessors;
internal int dwProcessorType;
internal int dwAllocationGranularity;
internal short wProcessorLevel;
internal short wProcessorRevision;
}

[StructLayout(LayoutKind.Sequential)]
internal struct MEMORYSTATUSEX
{
// The length field must be set to the size of this data structure.
internal int length;
internal int memoryLoad;
internal ulong totalPhys;
internal ulong availPhys;
internal ulong totalPageFile;
internal ulong availPageFile;
internal ulong totalVirtual;
internal ulong availVirtual;
internal ulong availExtendedVirtual;
}

[StructLayout(LayoutKind.Sequential)]
internal unsafe struct MEMORY_BASIC_INFORMATION
{
internal void* BaseAddress;
internal void* AllocationBase;
internal uint AllocationProtect;
internal UIntPtr RegionSize;
internal uint State;
internal uint Protect;
internal uint Type;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ namespace ILCompiler.DependencyAnalysis
/// to the TypeManager that contains the native layout info blob of interest, and the second item
/// is an offset into that native layout info blob
/// </summary>
class NativeLayoutSignatureNode : ObjectNode, ISymbolNode
public class NativeLayoutSignatureNode : ObjectNode, ISymbolNode
{
private TypeSystemEntity _identity;
private Utf8String _identityPrefix;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -386,7 +386,7 @@ public bool Equals(NativeLayoutSignatureKey other)
}

private NodeCache<NativeLayoutSignatureKey, NativeLayoutSignatureNode> _nativeLayoutSignatureNodes;
internal NativeLayoutSignatureNode NativeLayoutSignature(NativeLayoutSavedVertexNode signature, Utf8String identityPrefix, TypeSystemEntity identity)
public NativeLayoutSignatureNode NativeLayoutSignature(NativeLayoutSavedVertexNode signature, Utf8String identityPrefix, TypeSystemEntity identity)
{
return _nativeLayoutSignatureNodes.GetOrAdd(new NativeLayoutSignatureKey(signature, identityPrefix, identity));
}
Expand Down
8 changes: 4 additions & 4 deletions src/Native/Bootstrap/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ extern "C" void RhpUniversalTransition_DebugStepTailCall()
}
extern "C" void CCWAddRef()
{
throw "CCWAddRef";
throw "CCWAddRef";
}

void* RtRHeaderWrapper();
Expand Down Expand Up @@ -266,7 +266,7 @@ static const pfn c_classlibFunctions[] = {

#endif // !CPPCODEGEN

extern "C" void InitializeModules(void* osModule, void ** modules, int count);
extern "C" void InitializeModules(void* osModule, void ** modules, int count, void ** pClasslibFunctions, int nClasslibFunctions);

#if defined(_WIN32)
extern "C" int __managed__Main(int argc, wchar_t* argv[]);
Expand Down Expand Up @@ -308,9 +308,9 @@ int main(int argc, char* argv[])
#endif

#ifndef CPPCODEGEN
InitializeModules(osModule, __modules_a, (int)((__modules_z - __modules_a)));
InitializeModules(osModule, __modules_a, (int)((__modules_z - __modules_a)), (void **)&c_classlibFunctions, _countof(c_classlibFunctions));
#else // !CPPCODEGEN
InitializeModules(nullptr, (void**)RtRHeaderWrapper(), 2);
InitializeModules(nullptr, (void**)RtRHeaderWrapper(), 2, nullptr, 0);
#endif // !CPPCODEGEN

int retval;
Expand Down
29 changes: 27 additions & 2 deletions src/Native/Runtime/EHHelpers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
#include "threadstore.h"
#include "threadstore.inl"
#include "stressLog.h"
#include "rhbinder.h"
#include "eetype.h"

// Find the code manager containing the given address, which might be a return address from a managed function. The
// address may be to another managed function, or it may be to an unmanaged function. The address may also refer to
Expand All @@ -38,7 +40,6 @@ static ICodeManager * FindCodeManagerForClasslibFunction(void * address)
if (pCodeManager != NULL)
return pCodeManager;

// @TODO: CORERT: Do we need to make this work for CoreRT?
// Less common, we will look for the address in any of the sections of the module. This is slower, but is
// necessary for EEType pointers and jump stubs.
Module * pModule = pRI->FindModuleByAddress(address);
Expand Down Expand Up @@ -67,7 +68,7 @@ COOP_PINVOKE_HELPER(Boolean, RhpEHEnumNext, (EHEnum* pEHEnum, EHClause* pEHClaus
// Unmanaged helper to locate one of two classlib-provided functions that the runtime needs to
// implement throwing of exceptions out of Rtm, and fail-fast. This may return NULL if the classlib
// found via the provided address does not have the necessary exports.
COOP_PINVOKE_HELPER(void *, RhpGetClasslibFunction, (void * address, ClasslibFunctionId functionId))
COOP_PINVOKE_HELPER(void *, RhpGetClasslibFunctionFromCodeAddress, (void * address, ClasslibFunctionId functionId))
{
// Find the code manager for the given address, which is an address into some managed module. It could
// be code, or it could be an EEType. No matter what, it's an address into a managed module in some non-Rtm
Expand All @@ -83,6 +84,30 @@ COOP_PINVOKE_HELPER(void *, RhpGetClasslibFunction, (void * address, ClasslibFun
return pCodeManager->GetClasslibFunction(functionId);
}

// Unmanaged helper to locate one of two classlib-provided functions that the runtime needs to
// implement throwing of exceptions out of Rtm, and fail-fast. This may return NULL if the classlib
// found via the provided address does not have the necessary exports.
COOP_PINVOKE_HELPER(void *, RhpGetClasslibFunctionFromEEtype, (EEType * pEEtype, ClasslibFunctionId functionId))
{
if (pEEtype->HasTypeManager())
{
return pEEtype->GetTypeManagerPtr()->AsTypeManager()->GetClasslibFunction(functionId);
}
else
{
RuntimeInstance * pRI = GetRuntimeInstance();
Module * pModule = pRI->FindModuleByAddress(pEEtype);
if (pModule != NULL)
{
return pModule->GetClasslibFunction(functionId);
}
else
{
return NULL;
}
}
}

COOP_PINVOKE_HELPER(void, RhpValidateExInfoStack, ())
{
Thread * pThisThread = ThreadStore::GetCurrentThread();
Expand Down
8 changes: 8 additions & 0 deletions src/Native/Runtime/GCHelpers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -197,3 +197,11 @@ COOP_PINVOKE_HELPER(Int32, RhWaitForFullGCComplete, (Int32 millisecondsTimeout))
int timeout = millisecondsTimeout == -1 ? INFINITE : millisecondsTimeout;
return GCHeapUtilities::GetGCHeap()->WaitForFullGCComplete(millisecondsTimeout);
}

COOP_PINVOKE_HELPER(Int64, RhGetGCSegmentSize, ())
{
size_t first = GCHeapUtilities::GetGCHeap()->GetValidSegmentSize(Boolean_true);
size_t second = GCHeapUtilities::GetGCHeap()->GetValidSegmentSize(Boolean_false);

return (first > second) ? first : second;
}
4 changes: 2 additions & 2 deletions src/Native/Runtime/RuntimeInstance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -429,9 +429,9 @@ bool RuntimeInstance::RegisterTypeManager(TypeManager * pTypeManager)
return true;
}

COOP_PINVOKE_HELPER(TypeManagerHandle, RhpCreateTypeManager, (HANDLE osModule, void* pModuleHeader))
COOP_PINVOKE_HELPER(TypeManagerHandle, RhpCreateTypeManager, (HANDLE osModule, void* pModuleHeader, PTR_PTR_VOID pClasslibFunctions, UInt32 nClasslibFunctions))
{
TypeManager * typeManager = TypeManager::Create(osModule, pModuleHeader);
TypeManager * typeManager = TypeManager::Create(osModule, pModuleHeader, pClasslibFunctions, nClasslibFunctions);
GetRuntimeInstance()->RegisterTypeManager(typeManager);
return TypeManagerHandle::Create(typeManager);
}
Expand Down
19 changes: 15 additions & 4 deletions src/Native/Runtime/TypeManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
#include "TypeManager.h"

/* static */
TypeManager * TypeManager::Create(HANDLE osModule, void * pModuleHeader)
TypeManager * TypeManager::Create(HANDLE osModule, void * pModuleHeader, void** pClasslibFunctions, UInt32 nClasslibFunctions)
{
ReadyToRunHeader * pReadyToRunHeader = (ReadyToRunHeader *)pModuleHeader;

Expand All @@ -38,11 +38,12 @@ TypeManager * TypeManager::Create(HANDLE osModule, void * pModuleHeader)
if (pReadyToRunHeader->MajorVersion != ReadyToRunHeaderConstants::CurrentMajorVersion)
return nullptr;

return new (nothrow) TypeManager(osModule, pReadyToRunHeader);
return new (nothrow) TypeManager(osModule, pReadyToRunHeader, pClasslibFunctions, nClasslibFunctions);
}

TypeManager::TypeManager(HANDLE osModule, ReadyToRunHeader * pHeader)
: m_osModule(osModule), m_pHeader(pHeader), m_pDispatchMapTable(nullptr)
TypeManager::TypeManager(HANDLE osModule, ReadyToRunHeader * pHeader, void** pClasslibFunctions, UInt32 nClasslibFunctions)
: m_osModule(osModule), m_pHeader(pHeader), m_pDispatchMapTable(nullptr),
m_pClasslibFunctions(pClasslibFunctions), m_nClasslibFunctions(nClasslibFunctions)
{
int length;
m_pStaticsGCDataSection = (UInt8*)GetModuleSection(ReadyToRunSectionType::GCStaticRegion, &length);
Expand Down Expand Up @@ -73,6 +74,16 @@ void * TypeManager::GetModuleSection(ReadyToRunSectionType sectionId, int * leng
return nullptr;
}

void * TypeManager::GetClasslibFunction(ClasslibFunctionId functionId)
{
uint32_t id = (uint32_t)functionId;

if (id >= m_nClasslibFunctions)
return nullptr;

return m_pClasslibFunctions[id];
}

DispatchMap** TypeManager::GetDispatchMapLookupTable()
{
if (m_pDispatchMapTable == nullptr)
Expand Down
7 changes: 5 additions & 2 deletions src/Native/Runtime/TypeManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,18 @@ class TypeManager
UInt8* m_pStaticsGCDataSection;
UInt8* m_pThreadStaticsDataSection;
UInt32* m_pTlsIndex; // Pointer to TLS index if this module uses thread statics
void** m_pClasslibFunctions;
UInt32 m_nClasslibFunctions;

TypeManager(HANDLE osModule, ReadyToRunHeader * pHeader);
TypeManager(HANDLE osModule, ReadyToRunHeader * pHeader, void** pClasslibFunctions, UInt32 nClasslibFunctions);

public:
static TypeManager * Create(HANDLE osModule, void * pModuleHeader);
static TypeManager * Create(HANDLE osModule, void * pModuleHeader, void** pClasslibFunctions, UInt32 nClasslibFunctions);
void * GetModuleSection(ReadyToRunSectionType sectionId, int * length);
DispatchMap ** GetDispatchMapLookupTable();
void EnumStaticGCRefs(void * pfnCallback, void * pvCallbackData);
HANDLE GetOsModuleHandle();
void* GetClasslibFunction(ClasslibFunctionId functionId);

private:

Expand Down
2 changes: 1 addition & 1 deletion src/Runtime.Base/src/System/Runtime/EEType.Runtime.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ internal Exception GetClasslibException(ExceptionIDs id)
return RelatedParameterType->GetClasslibException(id);
}

return EH.GetClasslibException(id, GetAssociatedModuleAddress());
return EH.GetClasslibExceptionFromEEType(id, GetAssociatedModuleAddress());
#endif
}

Expand Down
44 changes: 40 additions & 4 deletions src/Runtime.Base/src/System/Runtime/ExceptionHandling.cs
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ internal static void FailFastViaClasslib(RhFailFastReason reason, object unhandl
{
// Find the classlib function that will fail fast. This is a RuntimeExport function from the
// classlib module, and is therefore managed-callable.
IntPtr pFailFastFunction = (IntPtr)InternalCalls.RhpGetClasslibFunction(classlibAddress,
IntPtr pFailFastFunction = (IntPtr)InternalCalls.RhpGetClasslibFunctionFromCodeAddress(classlibAddress,
ClassLibFunctionId.FailFast);

if (pFailFastFunction == IntPtr.Zero)
Expand Down Expand Up @@ -214,7 +214,7 @@ internal static unsafe void UnhandledExceptionFailFastViaClasslib(
RhFailFastReason reason, object unhandledException, IntPtr classlibAddress, ref ExInfo exInfo)
{
IntPtr pFailFastFunction =
(IntPtr)InternalCalls.RhpGetClasslibFunction(classlibAddress, ClassLibFunctionId.FailFast);
(IntPtr)InternalCalls.RhpGetClasslibFunctionFromCodeAddress(classlibAddress, ClassLibFunctionId.FailFast);

if (pFailFastFunction == IntPtr.Zero)
{
Expand Down Expand Up @@ -253,7 +253,7 @@ private enum RhEHFrameType
private static void AppendExceptionStackFrameViaClasslib(object exception, IntPtr IP,
ref bool isFirstRethrowFrame, ref bool isFirstFrame)
{
IntPtr pAppendStackFrame = (IntPtr)InternalCalls.RhpGetClasslibFunction(IP,
IntPtr pAppendStackFrame = (IntPtr)InternalCalls.RhpGetClasslibFunctionFromCodeAddress(IP,
ClassLibFunctionId.AppendExceptionStackFrame);

if (pAppendStackFrame != IntPtr.Zero)
Expand Down Expand Up @@ -284,7 +284,7 @@ internal static Exception GetClasslibException(ExceptionIDs id, IntPtr address)
// Find the classlib function that will give us the exception object we want to throw. This
// is a RuntimeExport function from the classlib module, and is therefore managed-callable.
IntPtr pGetRuntimeExceptionFunction =
(IntPtr)InternalCalls.RhpGetClasslibFunction(address, ClassLibFunctionId.GetRuntimeException);
(IntPtr)InternalCalls.RhpGetClasslibFunctionFromCodeAddress(address, ClassLibFunctionId.GetRuntimeException);

// Return the exception object we get from the classlib.
Exception e = null;
Expand All @@ -309,6 +309,42 @@ internal static Exception GetClasslibException(ExceptionIDs id, IntPtr address)
return e;
}

// Given an ExceptionID and an EEtype address, get an exception object of a type that the module containing
// the given address will understand. This finds the classlib-defined GetRuntimeException function and asks
// it for the exception object.
internal static Exception GetClasslibExceptionFromEEType(ExceptionIDs id, IntPtr pEEType)
{
// Find the classlib function that will give us the exception object we want to throw. This
// is a RuntimeExport function from the classlib module, and is therefore managed-callable.
IntPtr pGetRuntimeExceptionFunction = IntPtr.Zero;
if (pEEType != IntPtr.Zero)
{
pGetRuntimeExceptionFunction = (IntPtr)InternalCalls.RhpGetClasslibFunctionFromEEtype(pEEType, ClassLibFunctionId.GetRuntimeException);
}

// Return the exception object we get from the classlib.
Exception e = null;
try
{
e = CalliIntrinsics.Call<Exception>(pGetRuntimeExceptionFunction, id);
}
catch
{
// disallow all exceptions leaking out of callbacks
}

// If the helper fails to yield an object, then we fail-fast.
if (e == null)
{
FailFastViaClasslib(
RhFailFastReason.ClassLibDidNotTranslateExceptionID,
null,
pEEType);
}

return e;
}

// RhExceptionHandling_ functions are used to throw exceptions out of our asm helpers. We tail-call from
// the asm helpers to these functions, which performs the throw. The tail-call is important: it ensures that
// the stack is crawlable from within these functions.
Expand Down
Loading