diff options
author | Fadi Hanna <fadim@microsoft.com> | 2017-08-24 03:15:42 +0300 |
---|---|---|
committer | Fadi Hanna <fadim@microsoft.com> | 2017-08-24 03:15:42 +0300 |
commit | 537a942f3ff1b8c3b5b1eccf2e34d8e78c4e1ca4 (patch) | |
tree | 39e35249759f9024941992d6c26cfa3433e9ee43 /src/Native | |
parent | edc338eae11e2f849c14a172ad749b649b9fba92 (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.cpp | 188 | ||||
-rw-r--r-- | src/Native/Runtime/inc/ModuleHeaders.h | 1 |
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, |