Skip to content

Commit 9dfe1ba

Browse files
committed
Works on X64
1 parent 370fe6b commit 9dfe1ba

File tree

12 files changed

+161
-93
lines changed

12 files changed

+161
-93
lines changed

src/coreclr/inc/executableallocator.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@ class ExecutableAllocator
183183
static bool IsDoubleMappingEnabled();
184184

185185
// Release memory allocated via DoubleMapping for either templates or normal double mapped data
186-
void Release(void* pRX, bool releaseTemplate);
186+
void ReleaseWorker(void* pRX, bool releaseTemplate);
187187

188188
// Initialize the allocator instance
189189
bool Initialize();

src/coreclr/inc/loaderheap.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -501,13 +501,13 @@ class UnlockedInterleavedLoaderHeap : public UnlockedLoaderHeapBase
501501

502502
InterleavedStubFreeListNode *m_pFreeListHead;
503503

504-
InterleavedLoaderHeapConfig *m_pConfig;
504+
const InterleavedLoaderHeapConfig *m_pConfig;
505505

506506
#ifndef DACCESS_COMPILE
507507
protected:
508508
UnlockedInterleavedLoaderHeap(
509509
RangeList *pRangeList,
510-
InterleavedLoaderHeapConfig *pConfig);
510+
const InterleavedLoaderHeapConfig *pConfig);
511511

512512
virtual ~UnlockedInterleavedLoaderHeap();
513513
#endif
@@ -1045,7 +1045,7 @@ class InterleavedLoaderHeap : public UnlockedInterleavedLoaderHeap
10451045
public:
10461046
InterleavedLoaderHeap(RangeList *pRangeList,
10471047
BOOL fUnlocked,
1048-
InterleavedLoaderHeapConfig *pConfig,
1048+
const InterleavedLoaderHeapConfig *pConfig
10491049
)
10501050
: UnlockedInterleavedLoaderHeap(
10511051
pRangeList,

src/coreclr/minipal/Unix/doublemapping.cpp

Lines changed: 29 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include <fcntl.h>
1010
#include <unistd.h>
1111
#include <inttypes.h>
12+
#include <stdlib.h>
1213
#include <stdio.h>
1314
#include <string.h>
1415
#include <assert.h>
@@ -25,6 +26,11 @@
2526
#include "minipal.h"
2627
#include "minipal/cpufeatures.h"
2728

29+
#ifndef TARGET_APPLE
30+
#include <link.h>
31+
#include <dlfcn.h>
32+
#endif // TARGET_APPLE
33+
2834
#ifdef TARGET_APPLE
2935

3036
#include <mach/mach.h>
@@ -275,26 +281,32 @@ struct InitializeTemplateThunkLocals
275281

276282
static TemplateThunkMappingData *s_pThunkData = NULL;
277283

284+
static Elf32_Word Elf32_WordMin(Elf32_Word left, Elf32_Word right)
285+
{
286+
return left < right ? left : right;
287+
}
288+
278289
static int InitializeTemplateThunkMappingDataPhdrCallback(struct dl_phdr_info *info, size_t size, void *dataPtr)
279290
{
280291
InitializeTemplateThunkLocals *locals = (InitializeTemplateThunkLocals*)dataPtr;
281292

282-
if (info->dlpi_addr == locals->info.dli_fbase)
293+
if ((void*)info->dlpi_addr == locals->info.dli_fbase)
283294
{
284295
for (size_t j = 0; j < info->dlpi_phnum; j++)
285296
{
286-
if (locals.pTemplate < info->dlpi_phdr[j].p_vaddr)
297+
uint8_t* baseSectionAddr = (uint8_t*)locals->info.dli_fbase + info->dlpi_phdr[j].p_vaddr;
298+
if (locals->pTemplate < baseSectionAddr)
287299
{
288300
// Address is before the virtual address of this section begins
289301
continue;
290302
}
291303

292304
// Since this is all in support of mapping code from the file, we need to ensure that the region we find
293305
// is actually present in the file.
294-
Elf32_Word sizeOfSectionWhichCanBeMapped = min(info->dlpi_phdr[j].p_filesz, info->dlpi_phdr[j].p_memsz;
306+
Elf32_Word sizeOfSectionWhichCanBeMapped = Elf32_WordMin(info->dlpi_phdr[j].p_filesz, info->dlpi_phdr[j].p_memsz);
295307

296-
Elf32_Addr endAddressAllowedForTemplate = info->dlpi_phdr[j].p_vaddr + sizeOfSectionWhichCanBeMapped);
297-
if (locals.pTemplate >= endAddressAllowedForTemplate)
308+
uint8_t* endAddressAllowedForTemplate = baseSectionAddr + sizeOfSectionWhichCanBeMapped;
309+
if (locals->pTemplate >= endAddressAllowedForTemplate)
298310
{
299311
// Template is after the virtual address of this section ends (or the mappable region of the file)
300312
continue;
@@ -316,8 +328,8 @@ static int InitializeTemplateThunkMappingDataPhdrCallback(struct dl_phdr_info *i
316328

317329
locals->data.fdImage = fdImage;
318330
locals->data.offsetInFileOfStartOfSection = info->dlpi_phdr[j].p_offset;
319-
locals->data.addrOfStartOfSection = info->dlpi_phdr[j].p_vaddr;
320-
locals->data.addrOfEndOfSection = info->dlpi_phdr[j].p_vaddr + sizeOfSectionWhichCanBeMapped;
331+
locals->data.addrOfStartOfSection = baseSectionAddr;
332+
locals->data.addrOfEndOfSection = baseSectionAddr + sizeOfSectionWhichCanBeMapped;
321333
locals->data.imageTemplates = true;
322334
return 1; // We have found the result. Abort further processing.
323335
}
@@ -343,7 +355,7 @@ TemplateThunkMappingData *InitializeTemplateThunkMappingData(void* pTemplate)
343355
dl_iterate_phdr(InitializeTemplateThunkMappingDataPhdrCallback, &locals);
344356
}
345357

346-
if (locals.data->addrOfStartOfSection == NULL)
358+
if (locals.data.addrOfStartOfSection == NULL)
347359
{
348360
// This is the detail of thunk data which indicates if we were able to compute the template mapping data from the image.
349361

@@ -378,10 +390,10 @@ TemplateThunkMappingData *InitializeTemplateThunkMappingData(void* pTemplate)
378390
else
379391
{
380392
locals.data.fdImage = fd;
381-
locals->data.offsetInFileOfStartOfSection = 0;
382-
locals->data.addrOfStartOfSection = (void*)0x10000;
383-
locals->data.addrOfEndOfSection = ((uint8_t*)locals->data.addrOfStartOfSection) + maxFileSize;
384-
locals->data.imageTemplates = false;
393+
locals.data.offsetInFileOfStartOfSection = 0;
394+
locals.data.addrOfStartOfSection = (void*)0x10000;
395+
locals.data.addrOfEndOfSection = ((uint8_t*)locals.data.addrOfStartOfSection) + maxFileSize;
396+
locals.data.imageTemplates = false;
385397
}
386398
}
387399
}
@@ -440,8 +452,8 @@ void* VMToOSInterface::CreateTemplate(void* pImageTemplate, size_t templateSize,
440452
void* mappedMemory = mmap(NULL, templateSize, PROT_READ | PROT_WRITE, MAP_SHARED, pThunkData->fdImage, locationInFileToStoreGeneratedCode);
441453
if (mappedMemory != MAP_FAILED)
442454
{
443-
codePageGenerator(mappedMemory, mappedMemory, templateSize);
444-
munmap(mappedMemory);
455+
codePageGenerator((uint8_t*)mappedMemory, (uint8_t*)mappedMemory, templateSize);
456+
munmap(mappedMemory, templateSize);
445457
return ((uint8_t*)pThunkData->addrOfStartOfSection) + locationInFileToStoreGeneratedCode;
446458
}
447459
else
@@ -511,13 +523,13 @@ void* VMToOSInterface::AllocateThunksFromTemplate(void* pTemplate, size_t templa
511523
}
512524

513525
uint8_t* endOfTemplate = ((uint8_t*)pTemplate + templateSize);
514-
if (endOfTemplate > addrOfEndOfSection)
526+
if (endOfTemplate > pThunkData->addrOfEndOfSection)
515527
return NULL;
516528

517-
size_t sectionOffset = fileOffset = (uint8_t*)pTemplate - (uint8_t*)pThunkData->addrOfStartOfSection;
529+
size_t sectionOffset = (uint8_t*)pTemplate - (uint8_t*)pThunkData->addrOfStartOfSection;
518530
off_t fileOffset = pThunkData->offsetInFileOfStartOfSection + sectionOffset;
519531

520-
void *pStart = mmap(pStartHint, templateSize * 2, PROT_READ | PROT_WRITE, MAP_PRIVATE | (pStartSpecification != NULL ? MAP_FIXED : 0), 0, 0);
532+
void *pStart = mmap(pStartSpecification, templateSize * 2, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE | (pStartSpecification != NULL ? MAP_FIXED : 0), -1, 0);
521533
if (pStart == MAP_FAILED)
522534
{
523535
return NULL;

src/coreclr/minipal/minipal.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ class VMToOSInterface
8585
// Return:
8686
// NULL if creating the template fails
8787
// Non-NULL, a pointer to the template
88-
void* CreateTemplate(void* pImageTemplate, size_t templateSize, void (*codePageGenerator)(uint8_t* pageBase, uint8_t* pageBaseRX, size_t size))
88+
static void* CreateTemplate(void* pImageTemplate, size_t templateSize, void (*codePageGenerator)(uint8_t* pageBase, uint8_t* pageBaseRX, size_t size));
8989

9090
// Indicate if the AllocateThunksFromTemplate function respects the pStart address on this platform
9191
// Return:

src/coreclr/utilcode/executableallocator.cpp

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -555,7 +555,7 @@ void ExecutableAllocator::ReleaseWorker(void* pRX, bool releaseTemplate)
555555

556556
if (releaseTemplate)
557557
{
558-
if (!VMToOSInterface::FreeThunksFromTemplate(pThunks, pBlock->size / 2))
558+
if (!VMToOSInterface::FreeThunksFromTemplate(pRX, pBlock->size / 2))
559559
{
560560
g_fatalErrorHandler(COR_E_EXECUTIONENGINE, W("Releasing the template mapped memory failed"));
561561
}
@@ -991,18 +991,25 @@ void* ExecutableAllocator::AllocateThunksFromTemplate(void *pTemplate, size_t te
991991
return NULL;
992992
}
993993

994-
void *pTemplateAddressAllocated = VMToOSInterface::AllocateThunksFromTemplate(pTemplate, templateSize, pTemplateAddress);
994+
void* result = VMToOSInterface::ReserveDoubleMappedMemory(m_doubleMemoryMapperHandle, block->offset, templateSize * 2, 0, 0);
995995

996-
if (pTemplateAddressAllocated != NULL)
996+
if (result != NULL)
997997
{
998-
block->baseRX = pTemplateAddressAllocated;
998+
block->baseRX = result;
999999
AddRXBlock(block);
10001000
}
10011001
else
10021002
{
10031003
BackoutBlock(block, isFreeBlock);
10041004
}
10051005

1006+
void *pTemplateAddressAllocated = VMToOSInterface::AllocateThunksFromTemplate(pTemplate, templateSize, block->baseRX);
1007+
1008+
if (pTemplateAddressAllocated == NULL)
1009+
{
1010+
ReleaseWorker(block->baseRX, false);
1011+
}
1012+
10061013
return pTemplateAddressAllocated;
10071014
}
10081015
else
@@ -1023,3 +1030,8 @@ void ExecutableAllocator::FreeThunksFromTemplate(void *pThunks, size_t templateS
10231030
VMToOSInterface::FreeThunksFromTemplate(pThunks, templateSize);
10241031
}
10251032
}
1033+
1034+
void* ExecutableAllocator::CreateTemplate(void* templateInImage, size_t templateSize, void (*codePageGenerator)(BYTE* pageBase, BYTE* pageBaseRX, SIZE_T size))
1035+
{
1036+
return VMToOSInterface::CreateTemplate(templateInImage, templateSize, codePageGenerator);
1037+
}

src/coreclr/utilcode/interleavedloaderheap.cpp

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,13 @@ namespace
3333

3434
UnlockedInterleavedLoaderHeap::UnlockedInterleavedLoaderHeap(
3535
RangeList *pRangeList,
36-
void (*codePageGenerator)(BYTE* pageBase, BYTE* pageBaseRX, SIZE_T size),
37-
DWORD dwGranularity) :
36+
const InterleavedLoaderHeapConfig *pConfig) :
3837
UnlockedLoaderHeapBase(LoaderHeapImplementationKind::Interleaved),
39-
m_pFreeListHead(NULL)
38+
m_pEndReservedRegion(NULL),
39+
m_dwGranularity(pConfig->StubSize),
40+
m_pRangeList(pRangeList),
41+
m_pFreeListHead(NULL),
42+
m_pConfig(pConfig)
4043
{
4144
CONTRACTL
4245
{
@@ -46,15 +49,7 @@ UnlockedInterleavedLoaderHeap::UnlockedInterleavedLoaderHeap(
4649
}
4750
CONTRACTL_END;
4851

49-
m_pEndReservedRegion = NULL;
50-
51-
m_pRangeList = pRangeList;
52-
5352
_ASSERTE((GetStubCodePageSize() % GetOsPageSize()) == 0); // Stub code page size MUST be in increments of the page size. (Really it must be a power of 2 as well, but this is good enough)
54-
m_dwGranularity = dwGranularity;
55-
56-
_ASSERTE(codePageGenerator != NULL);
57-
m_codePageGenerator = codePageGenerator;
5853
}
5954

6055
// ~LoaderHeap is not synchronised (obviously)
@@ -134,7 +129,7 @@ BOOL UnlockedInterleavedLoaderHeap::CommitPages(void* pData, size_t dwSizeToComm
134129
}
135130

136131
ExecutableWriterHolder<BYTE> codePageWriterHolder((BYTE*)pData, dwSizeToCommitPart, ExecutableAllocator::DoNotAddToCache);
137-
m_codePageGenerator(codePageWriterHolder.GetRW(), (BYTE*)pData, dwSizeToCommitPart);
132+
m_pConfig->CodePageGenerator(codePageWriterHolder.GetRW(), (BYTE*)pData, dwSizeToCommitPart);
138133
FlushInstructionCache(GetCurrentProcess(), pData, dwSizeToCommitPart);
139134

140135
return TRUE;
@@ -288,7 +283,7 @@ BOOL UnlockedInterleavedLoaderHeap::GetMoreCommittedPages(size_t dwMinSize)
288283
}
289284
}
290285

291-
m_dwTotalAlloc += dwSizeToCommit;
286+
m_dwTotalAlloc += dwSizeToReserve;
292287

293288
pNewBlock.SuppressRelease();
294289
newAllocatedThunks.SuppressRelease();
@@ -551,7 +546,9 @@ void *UnlockedInterleavedLoaderHeap::UnlockedAllocStub(
551546

552547
void InitializeLoaderHeapConfig(InterleavedLoaderHeapConfig *pConfig, size_t stubSize, void* templateInImage, void (*codePageGenerator)(BYTE* pageBase, BYTE* pageBaseRX, SIZE_T size))
553548
{
554-
549+
pConfig->StubSize = stubSize;
550+
pConfig->Template = ExecutableAllocator::Instance()->CreateTemplate(templateInImage, GetStubCodePageSize(), codePageGenerator);
551+
pConfig->CodePageGenerator = codePageGenerator;
555552
}
556553

557554
#endif // #ifndef DACCESS_COMPILE

0 commit comments

Comments
 (0)