Skip to content

Commit dd33442

Browse files
authored
Restore personality routine outside Windows (#115729)
`IsIPInEpilog` depends on this to exist. Without it, hijacking is broken outside Windows.
1 parent 86f6fa9 commit dd33442

File tree

5 files changed

+24
-20
lines changed

5 files changed

+24
-20
lines changed

src/coreclr/debug/daccess/fntableaccess.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,13 @@ struct FakeHeapList
3030
size_t maxCodeHeapSize;
3131
size_t reserveForJumpStubs;
3232
DWORD_PTR pLoaderAllocator;
33-
#if defined(TARGET_64BIT) && defined(TARGET_WINDOWS)
33+
#if defined(TARGET_64BIT)
3434
DWORD_PTR CLRPersonalityRoutine;
3535
#endif
3636

3737
DWORD_PTR GetModuleBase()
3838
{
39-
#if defined(TARGET_64BIT) && defined(TARGET_WINDOWS)
39+
#if defined(TARGET_64BIT)
4040
return CLRPersonalityRoutine;
4141
#else
4242
return mapBase;

src/coreclr/vm/codeman.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2430,7 +2430,7 @@ HeapList* LoaderCodeHeap::CreateCodeHeap(CodeHeapRequestInfo *pInfo, LoaderHeap
24302430
bool fAllocatedFromEmergencyJumpStubReserve = false;
24312431

24322432
size_t allocationSize = pCodeHeap->m_LoaderHeap.AllocMem_TotalSize(initialRequestSize);
2433-
#if defined(TARGET_64BIT) && defined(TARGET_WINDOWS)
2433+
#if defined(TARGET_64BIT)
24342434
if (!pInfo->IsInterpreted())
24352435
{
24362436
allocationSize += pCodeHeap->m_LoaderHeap.AllocMem_TotalSize(JUMP_ALLOCATE_SIZE);
@@ -2490,14 +2490,15 @@ HeapList* LoaderCodeHeap::CreateCodeHeap(CodeHeapRequestInfo *pInfo, LoaderHeap
24902490
// this first allocation is critical as it sets up correctly the loader heap info
24912491
HeapList *pHp = new HeapList;
24922492

2493-
#if defined(TARGET_64BIT) && defined(TARGET_WINDOWS)
2493+
#if defined(TARGET_64BIT)
24942494
if (pInfo->IsInterpreted())
24952495
{
24962496
pHp->CLRPersonalityRoutine = NULL;
24972497
pCodeHeap->m_LoaderHeap.ReservePages(1);
24982498
}
24992499
else
25002500
{
2501+
// Set the personality routine. This is needed even outside Windows because IsIPInEpilog relies on it being set.
25012502
pHp->CLRPersonalityRoutine = (BYTE *)pCodeHeap->m_LoaderHeap.AllocMemForCode_NoThrow(0, JUMP_ALLOCATE_SIZE, sizeof(void*), 0);
25022503
}
25032504
#else
@@ -2531,7 +2532,7 @@ HeapList* LoaderCodeHeap::CreateCodeHeap(CodeHeapRequestInfo *pInfo, LoaderHeap
25312532
pHp->mapBase = ROUND_DOWN_TO_PAGE(pHp->startAddress); // round down to next lower page align
25322533
size_t nibbleMapSize = HEAP2MAPSIZE(ROUND_UP_TO_PAGE(heapSize));
25332534
pHp->pHdrMap = (DWORD*)(void*)pJitMetaHeap->AllocMem(S_SIZE_T(nibbleMapSize));
2534-
#if defined(TARGET_64BIT) && defined(TARGET_WINDOWS)
2535+
#if defined(TARGET_64BIT)
25352536
if (pHp->CLRPersonalityRoutine != NULL)
25362537
{
25372538
ExecutableWriterHolder<BYTE> personalityRoutineWriterHolder(pHp->CLRPersonalityRoutine, 12);
@@ -2660,7 +2661,7 @@ HeapList* EECodeGenManager::NewCodeHeap(CodeHeapRequestInfo *pInfo, DomainCodeHe
26602661

26612662
size_t reserveSize = initialRequestSize;
26622663

2663-
#if defined(TARGET_64BIT) && defined(TARGET_WINDOWS)
2664+
#if defined(TARGET_64BIT)
26642665
if (!pInfo->IsInterpreted())
26652666
{
26662667
reserveSize += JUMP_ALLOCATE_SIZE;

src/coreclr/vm/codeman.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -534,13 +534,13 @@ struct HeapList
534534
size_t reserveForJumpStubs; // Amount of memory reserved for jump stubs in this block
535535

536536
PTR_LoaderAllocator pLoaderAllocator; // LoaderAllocator of HeapList
537-
#if defined(TARGET_64BIT) && defined(TARGET_WINDOWS)
537+
#if defined(TARGET_64BIT)
538538
BYTE* CLRPersonalityRoutine; // jump thunk to personality routine, NULL if there is no personality routine (e.g. interpreter code heap)
539539
#endif
540540

541541
TADDR GetModuleBase()
542542
{
543-
#if defined(TARGET_64BIT) && defined(TARGET_WINDOWS)
543+
#if defined(TARGET_64BIT)
544544
return (CLRPersonalityRoutine != NULL) ? (TADDR)CLRPersonalityRoutine : (TADDR)mapBase;
545545
#else
546546
return (TADDR)mapBase;
@@ -2281,7 +2281,7 @@ class ExecutionManager
22812281
BOOL Acquired();
22822282
};
22832283

2284-
#if defined(TARGET_64BIT) && defined(TARGET_WINDOWS)
2284+
#if defined(TARGET_64BIT)
22852285
static ULONG GetCLRPersonalityRoutineValue()
22862286
{
22872287
LIMITED_METHOD_CONTRACT;

src/coreclr/vm/dynamicmethod.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -399,7 +399,7 @@ HeapList* HostCodeHeap::InitializeHeapList(CodeHeapRequestInfo *pInfo)
399399
// Add TrackAllocation, HeapList and very conservative padding to make sure we have enough for the allocation
400400
ReserveBlockSize += sizeof(TrackAllocation) + HOST_CODEHEAP_SIZE_ALIGN + 0x100;
401401

402-
#if defined(TARGET_64BIT) && defined(TARGET_WINDOWS)
402+
#if defined(TARGET_64BIT)
403403
ReserveBlockSize += JUMP_ALLOCATE_SIZE;
404404
#endif
405405

@@ -435,7 +435,7 @@ HeapList* HostCodeHeap::InitializeHeapList(CodeHeapRequestInfo *pInfo)
435435

436436
TrackAllocation *pTracker = NULL;
437437

438-
#if defined(TARGET_64BIT) && defined(TARGET_WINDOWS)
438+
#if defined(TARGET_64BIT)
439439
#ifdef FEATURE_INTERPRETER
440440
if (pInfo->IsInterpreted())
441441
{
@@ -474,7 +474,7 @@ HeapList* HostCodeHeap::InitializeHeapList(CodeHeapRequestInfo *pInfo)
474474
pHp->maxCodeHeapSize = m_TotalBytesAvailable - (pTracker ? pTracker->size : 0);
475475
pHp->reserveForJumpStubs = 0;
476476

477-
#if defined(TARGET_64BIT) && defined(TARGET_WINDOWS)
477+
#if defined(TARGET_64BIT)
478478
if (pHp->CLRPersonalityRoutine != NULL)
479479
{
480480
ExecutableWriterHolder<BYTE> personalityRoutineWriterHolder(pHp->CLRPersonalityRoutine, 12);

src/coreclr/vm/jitinterface.cpp

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11385,7 +11385,7 @@ void CEECodeGenInfo::CompressDebugInfo(PCODE nativeEntry)
1138511385

1138611386
void reservePersonalityRoutineSpace(uint32_t &unwindSize)
1138711387
{
11388-
#if defined(TARGET_AMD64)
11388+
#ifdef TARGET_AMD64
1138911389
// Note that the count of unwind codes (2 bytes each) is stored as a UBYTE
1139011390
// So the largest size could be 510 bytes, plus the header and language
1139111391
// specific stuff. This can't overflow.
@@ -11397,10 +11397,10 @@ void reservePersonalityRoutineSpace(uint32_t &unwindSize)
1139711397
_ASSERTE(IS_ALIGNED(unwindSize, sizeof(ULONG)));
1139811398
#endif // TARGET_AMD64
1139911399

11400-
#if !defined(TARGET_X86) && defined(TARGET_WINDOWS)
11400+
#ifndef TARGET_X86
1140111401
// Add space for personality routine
1140211402
unwindSize += sizeof(ULONG);
11403-
#endif // !TARGET_X86 && TARGET_WINDOWS
11403+
#endif // !TARGET_X86
1140411404
}
1140511405

1140611406
// Reserve memory for the method/funclet's unwind information.
@@ -11590,19 +11590,22 @@ void CEEJitInfo::allocUnwindInfo (
1159011590

1159111591
memcpy(pUnwindInfoRW, pUnwindBlock, unwindSize);
1159211592

11593-
#if !defined(TARGET_X86) && defined(TARGET_WINDOWS)
11594-
#ifdef TARGET_AMD64
11593+
#if defined(TARGET_AMD64)
1159511594
pUnwindInfoRW->Flags = UNW_FLAG_EHANDLER | UNW_FLAG_UHANDLER;
1159611595

1159711596
ULONG * pPersonalityRoutineRW = (ULONG*)ALIGN_UP(&(pUnwindInfoRW->UnwindCode[pUnwindInfoRW->CountOfUnwindCodes]), sizeof(ULONG));
1159811597
*pPersonalityRoutineRW = ExecutionManager::GetCLRPersonalityRoutineValue();
11599-
#else // TARGET_AMD64
11598+
#elif defined(TARGET_64BIT)
1160011599
*(LONG *)pUnwindInfoRW |= (1 << 20); // X bit
1160111600

1160211601
ULONG * pPersonalityRoutineRW = (ULONG*)((BYTE *)pUnwindInfoRW + ALIGN_UP(unwindSize, sizeof(ULONG)));
1160311602
*pPersonalityRoutineRW = ExecutionManager::GetCLRPersonalityRoutineValue();
11604-
#endif // TARGET_AMD64
11605-
#endif // !TARGET_X86 && TARGET_WINDOWS
11603+
#elif defined(TARGET_ARM)
11604+
*(LONG *)pUnwindInfoRW |= (1 << 20); // X bit
11605+
11606+
ULONG * pPersonalityRoutineRW = (ULONG*)((BYTE *)pUnwindInfoRW + ALIGN_UP(unwindSize, sizeof(ULONG)));
11607+
*pPersonalityRoutineRW = (TADDR)ProcessCLRException - baseAddress;
11608+
#endif
1160611609

1160711610
EE_TO_JIT_TRANSITION();
1160811611
#else // FEATURE_EH_FUNCLETS

0 commit comments

Comments
 (0)