Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/corert.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFadi Hanna <fadim@microsoft.com>2017-08-24 03:15:42 +0300
committerFadi Hanna <fadim@microsoft.com>2017-08-24 03:15:42 +0300
commit537a942f3ff1b8c3b5b1eccf2e34d8e78c4e1ca4 (patch)
tree39e35249759f9024941992d6c26cfa3433e9ee43 /src/Native
parentedc338eae11e2f849c14a172ad749b649b9fba92 (diff)
CoreRT implementation for the GetCodeTarget API, to decode unboxing stubs
[tfs-changeset: 1671610]
Diffstat (limited to 'src/Native')
-rw-r--r--src/Native/Runtime/MiscHelpers.cpp188
-rw-r--r--src/Native/Runtime/inc/ModuleHeaders.h1
2 files changed, 99 insertions, 90 deletions
diff --git a/src/Native/Runtime/MiscHelpers.cpp b/src/Native/Runtime/MiscHelpers.cpp
index 0765eb3bb..49885a5a1 100644
--- a/src/Native/Runtime/MiscHelpers.cpp
+++ b/src/Native/Runtime/MiscHelpers.cpp
@@ -464,117 +464,125 @@ inline Int32 GetThumb2BlRel24(UInt16 * p)
// Given a pointer to code, find out if this points to an import stub
// or unboxing stub, and if so, return the address that stub jumps to
-COOP_PINVOKE_HELPER(UInt8 *, RhGetCodeTarget, (UInt8 * pCodeOrg))
+COOP_PINVOKE_HELPER(UInt8 *, RhGetCodeTarget, (TypeManagerHandle *pTypeManagerHandle, UInt8 * pCodeOrg))
{
- // Search for the module containing the code
- FOREACH_MODULE(pModule)
+ Module * pModule = NULL;
+ TypeManagerHandle typeManagerHandle = *pTypeManagerHandle;
+
+ if (typeManagerHandle.IsTypeManager())
{
- // If the code pointer doesn't point to a module's stub range,
- // it can't be pointing to a stub
+ Int32 length;
+ UInt8* pUnboxingStubsRegion = (UInt8*)typeManagerHandle.AsTypeManager()->GetModuleSection(ReadyToRunSectionType::UnboxingStubsRegion, &length);
+ if (pUnboxingStubsRegion == NULL || pCodeOrg < pUnboxingStubsRegion || pCodeOrg >= (pUnboxingStubsRegion + length))
+ return pCodeOrg;
+ }
+ else
+ {
+ pModule = GetRuntimeInstance()->FindModuleByOsHandle(typeManagerHandle.AsOsModule());
+
if (!pModule->ContainsStubAddress(pCodeOrg))
- continue;
+ return pCodeOrg;
+ }
- bool unboxingStub = false;
+ bool unboxingStub = false;
#ifdef _TARGET_AMD64_
- UInt8 * pCode = pCodeOrg;
+ UInt8 * pCode = pCodeOrg;
- // is this "add rcx,8"?
- if (pCode[0] == 0x48 && pCode[1] == 0x83 && pCode[2] == 0xc1 && pCode[3] == 0x08)
- {
- // unboxing sequence
- unboxingStub = true;
- pCode += 4;
- }
- // is this an indirect jump?
- if (pCode[0] == 0xff && pCode[1] == 0x25)
- {
- // normal import stub - dist to IAT cell is relative to the point *after* the instruction
- Int32 distToIatCell = *(Int32 *)&pCode[2];
- UInt8 ** pIatCell = (UInt8 **)(pCode + 6 + distToIatCell);
- ASSERT(pModule->ContainsDataAddress(pIatCell));
- return *pIatCell;
- }
- // is this an unboxing stub followed by a relative jump?
- else if (unboxingStub && pCode[0] == 0xe9)
- {
- // relatie jump - dist is relative to the point *after* the instruction
- Int32 distToTarget = *(Int32 *)&pCode[1];
- UInt8 * target = pCode + 5 + distToTarget;
- return target;
- }
- return pCodeOrg;
+ // is this "add rcx,8"?
+ if (pCode[0] == 0x48 && pCode[1] == 0x83 && pCode[2] == 0xc1 && pCode[3] == 0x08)
+ {
+ // unboxing sequence
+ unboxingStub = true;
+ pCode += 4;
+ }
+ // is this an indirect jump?
+ if (pCode[0] == 0xff && pCode[1] == 0x25)
+ {
+ // normal import stub - dist to IAT cell is relative to the point *after* the instruction
+ Int32 distToIatCell = *(Int32 *)&pCode[2];
+ UInt8 ** pIatCell = (UInt8 **)(pCode + 6 + distToIatCell);
+ ASSERT(pModule == NULL || pModule->ContainsDataAddress(pIatCell));
+ return *pIatCell;
+ }
+ // is this an unboxing stub followed by a relative jump?
+ else if (unboxingStub && pCode[0] == 0xe9)
+ {
+ // relatie jump - dist is relative to the point *after* the instruction
+ Int32 distToTarget = *(Int32 *)&pCode[1];
+ UInt8 * target = pCode + 5 + distToTarget;
+ return target;
+ }
#elif _TARGET_X86_
- UInt8 * pCode = pCodeOrg;
+ UInt8 * pCode = pCodeOrg;
- // is this "add ecx,4"?
- if (pCode[0] == 0x83 && pCode[1] == 0xc1 && pCode[2] == 0x04)
- {
- // unboxing sequence
- unboxingStub = true;
- pCode += 3;
- }
- // is this an indirect jump?
- if (pCode[0] == 0xff && pCode[1] == 0x25)
- {
- // normal import stub - address of IAT follows
- UInt8 **pIatCell = *(UInt8 ***)&pCode[2];
- ASSERT(pModule->ContainsDataAddress(pIatCell));
- return *pIatCell;
- }
- // is this an unboxing stub followed by a relative jump?
- else if (unboxingStub && pCode[0] == 0xe9)
- {
- // relatie jump - dist is relative to the point *after* the instruction
- Int32 distToTarget = *(Int32 *)&pCode[1];
- UInt8 * pTarget = pCode + 5 + distToTarget;
- return pTarget;
- }
- return pCodeOrg;
+ // is this "add ecx,4"?
+ if (pCode[0] == 0x83 && pCode[1] == 0xc1 && pCode[2] == 0x04)
+ {
+ // unboxing sequence
+ unboxingStub = true;
+ pCode += 3;
+ }
+ // is this an indirect jump?
+ if (pCode[0] == 0xff && pCode[1] == 0x25)
+ {
+ // normal import stub - address of IAT follows
+ UInt8 **pIatCell = *(UInt8 ***)&pCode[2];
+ ASSERT(pModule == NULL || pModule->ContainsDataAddress(pIatCell));
+ return *pIatCell;
+ }
+ // is this an unboxing stub followed by a relative jump?
+ else if (unboxingStub && pCode[0] == 0xe9)
+ {
+ // relatie jump - dist is relative to the point *after* the instruction
+ Int32 distToTarget = *(Int32 *)&pCode[1];
+ UInt8 * pTarget = pCode + 5 + distToTarget;
+ return pTarget;
+ }
#elif _TARGET_ARM_
- const UInt16 THUMB_BIT = 1;
- UInt16 * pCode = (UInt16 *)((size_t)pCodeOrg & ~THUMB_BIT);
- // is this "adds r0,4"?
- if (pCode[0] == 0x3004)
- {
- // unboxing sequence
- unboxingStub = true;
- pCode += 1;
- }
- // is this movw r12,#imm16; movt r12,#imm16; ldr pc,[r12]
- // or movw r12,#imm16; movt r12,#imm16; bx r12
- if ((pCode[0] & 0xfbf0) == 0xf240 && (pCode[1] & 0x0f00) == 0x0c00
- && (pCode[2] & 0xfbf0) == 0xf2c0 && (pCode[3] & 0x0f00) == 0x0c00
- && ((pCode[4] == 0xf8dc && pCode[5] == 0xf000) || pCode[4] == 0x4760))
+ const UInt16 THUMB_BIT = 1;
+ UInt16 * pCode = (UInt16 *)((size_t)pCodeOrg & ~THUMB_BIT);
+ // is this "adds r0,4"?
+ if (pCode[0] == 0x3004)
+ {
+ // unboxing sequence
+ unboxingStub = true;
+ pCode += 1;
+ }
+ // is this movw r12,#imm16; movt r12,#imm16; ldr pc,[r12]
+ // or movw r12,#imm16; movt r12,#imm16; bx r12
+ if ((pCode[0] & 0xfbf0) == 0xf240 && (pCode[1] & 0x0f00) == 0x0c00
+ && (pCode[2] & 0xfbf0) == 0xf2c0 && (pCode[3] & 0x0f00) == 0x0c00
+ && ((pCode[4] == 0xf8dc && pCode[5] == 0xf000) || pCode[4] == 0x4760))
+ {
+ if (pCode[4] == 0xf8dc && pCode[5] == 0xf000)
{
- if (pCode[4] == 0xf8dc && pCode[5] == 0xf000)
- {
- // ldr pc,[r12]
- UInt8 **pIatCell = (UInt8 **)GetThumb2Mov32(pCode);
- return *pIatCell;
- }
- else if (pCode[4] == 0x4760)
- {
- // bx r12
- return (UInt8 *)GetThumb2Mov32(pCode);
- }
+ // ldr pc,[r12]
+ UInt8 **pIatCell = (UInt8 **)GetThumb2Mov32(pCode);
+ return *pIatCell;
}
- // is this an unboxing stub followed by a relative jump?
- else if (unboxingStub && (pCode[0] & 0xf800) == 0xf000 && (pCode[1] & 0xd000) == 0x9000)
+ else if (pCode[4] == 0x4760)
{
- Int32 distToTarget = GetThumb2BlRel24(pCode);
- UInt8 * pTarget = (UInt8 *)(pCode + 2) + distToTarget + THUMB_BIT;
- return (UInt8 *)pTarget;
+ // bx r12
+ return (UInt8 *)GetThumb2Mov32(pCode);
}
+ }
+ // is this an unboxing stub followed by a relative jump?
+ else if (unboxingStub && (pCode[0] & 0xf800) == 0xf000 && (pCode[1] & 0xd000) == 0x9000)
+ {
+ Int32 distToTarget = GetThumb2BlRel24(pCode);
+ UInt8 * pTarget = (UInt8 *)(pCode + 2) + distToTarget + THUMB_BIT;
+ return (UInt8 *)pTarget;
+ }
+
#elif _TARGET_ARM64_
PORTABILITY_ASSERT("@TODO: FIXME:ARM64");
+
#else
#error 'Unsupported Architecture'
#endif
- }
- END_FOREACH_MODULE;
return pCodeOrg;
}
diff --git a/src/Native/Runtime/inc/ModuleHeaders.h b/src/Native/Runtime/inc/ModuleHeaders.h
index 33f77c458..407e3ed2c 100644
--- a/src/Native/Runtime/inc/ModuleHeaders.h
+++ b/src/Native/Runtime/inc/ModuleHeaders.h
@@ -52,6 +52,7 @@ enum class ReadyToRunSectionType
ThreadStaticGCDescRegion = 209,
ThreadStaticIndex = 210,
LoopHijackFlag = 211,
+ UnboxingStubsRegion = 212,
// Sections 300 - 399 are reserved for RhFindBlob backwards compatibility
ReadonlyBlobRegionStart = 300,