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
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
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
9 changes: 7 additions & 2 deletions src/Runtime.Base/src/System/Runtime/InternalCalls.cs
Original file line number Diff line number Diff line change
Expand Up @@ -224,10 +224,15 @@ internal static Int32 RhEndNoGCRegion()
[ManuallyManaged(GcPollPolicy.Never)]
internal extern static unsafe IntPtr RhpUpdateDispatchCellCache(IntPtr pCell, IntPtr pTargetCode, EEType* pInstanceType, ref DispatchCellInfo newCellInfo);

[RuntimeImport(Redhawk.BaseName, "RhpGetClasslibFunction")]
[RuntimeImport(Redhawk.BaseName, "RhpGetClasslibFunctionFromCodeAddress")]
[MethodImpl(MethodImplOptions.InternalCall)]
[ManuallyManaged(GcPollPolicy.Never)]
internal extern static unsafe void* RhpGetClasslibFunction(IntPtr address, EH.ClassLibFunctionId id);
internal extern static unsafe void* RhpGetClasslibFunctionFromCodeAddress(IntPtr address, EH.ClassLibFunctionId id);

[RuntimeImport(Redhawk.BaseName, "RhpGetClasslibFunctionFromEEtype")]
[MethodImpl(MethodImplOptions.InternalCall)]
[ManuallyManaged(GcPollPolicy.Never)]
internal extern static unsafe void* RhpGetClasslibFunctionFromEEtype(IntPtr pEEType, EH.ClassLibFunctionId id);

//
// StackFrameIterator
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -468,7 +468,7 @@ internal static unsafe bool RhFindBlob(TypeManagerHandle typeManagerHandle, uint

[MethodImplAttribute(MethodImplOptions.InternalCall)]
[RuntimeImport(RuntimeLibrary, "RhpCreateTypeManager")]
internal static extern unsafe TypeManagerHandle RhpCreateTypeManager(IntPtr osModule, IntPtr moduleHeader);
internal static extern unsafe TypeManagerHandle RhpCreateTypeManager(IntPtr osModule, IntPtr moduleHeader, IntPtr* pClasslibFunctions, int nClasslibFunctions);

[MethodImplAttribute(MethodImplOptions.InternalCall)]
[RuntimeImport(RuntimeLibrary, "RhpRegisterOsModule")]
Expand Down
2 changes: 1 addition & 1 deletion src/Test.CoreLib/src/System/Runtime/RuntimeImports.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ internal static IntPtr RhGetModuleSection(TypeManagerHandle module, ReadyToRunSe

[MethodImplAttribute(MethodImplOptions.InternalCall)]
[RuntimeImport(RuntimeLibrary, "RhpCreateTypeManager")]
internal static extern unsafe TypeManagerHandle RhpCreateTypeManager(IntPtr osModule, IntPtr moduleHeader);
internal static extern unsafe TypeManagerHandle RhpCreateTypeManager(IntPtr osModule, IntPtr moduleHeader, IntPtr* pClasslibFunctions, int nClasslibFunctions);

[MethodImplAttribute(MethodImplOptions.InternalCall)]
[RuntimeImport(RuntimeLibrary, "RhpRegisterOsModule")]
Expand Down