diff --git a/src/coreclr/debug/daccess/request.cpp b/src/coreclr/debug/daccess/request.cpp index b20be8fd8eca41..8aedb25b1720eb 100644 --- a/src/coreclr/debug/daccess/request.cpp +++ b/src/coreclr/debug/daccess/request.cpp @@ -1232,9 +1232,9 @@ HRESULT ClrDataAccess::GetTieredVersions( PTR_Module pModule = (PTR_Module)pMD->GetModule(); if (pModule->IsReadyToRun()) { - PTR_PEImageLayout pImage = pModule->GetReadyToRunInfo()->GetImage(); + PTR_ReadyToRunLoadedImage pImage = pModule->GetReadyToRunInfo()->GetImage(); r2rImageBase = dac_cast(pImage->GetBase()); - r2rImageEnd = r2rImageBase + pImage->GetSize(); + r2rImageEnd = r2rImageBase + pImage->GetVirtualSize(); } } diff --git a/src/coreclr/vm/ceeload.cpp b/src/coreclr/vm/ceeload.cpp index 68cc4fdc9f54f8..1860164c62e19a 100644 --- a/src/coreclr/vm/ceeload.cpp +++ b/src/coreclr/vm/ceeload.cpp @@ -2060,7 +2060,7 @@ BOOL Module::IsVisibleToDebugger() return TRUE; } -PEImageLayout * Module::GetReadyToRunImage() +ReadyToRunLoadedImage * Module::GetReadyToRunImage() { LIMITED_METHOD_CONTRACT; @@ -3583,7 +3583,7 @@ void Module::RunEagerFixupsUnlocked() { COUNT_T nSections; PTR_READYTORUN_IMPORT_SECTION pSections = GetImportSections(&nSections); - PEImageLayout *pNativeImage = GetReadyToRunImage(); + ReadyToRunLoadedImage *pNativeImage = GetReadyToRunImage(); for (COUNT_T iSection = 0; iSection < nSections; iSection++) { diff --git a/src/coreclr/vm/ceeload.h b/src/coreclr/vm/ceeload.h index ddd8d9f6b65284..5dc96502eb96af 100644 --- a/src/coreclr/vm/ceeload.h +++ b/src/coreclr/vm/ceeload.h @@ -1445,7 +1445,7 @@ class Module : public ModuleBase LPCUTF8 GetDebugName() { WRAPPER_NO_CONTRACT; return m_pPEAssembly->GetDebugName(); } #endif - PEImageLayout * GetReadyToRunImage(); + ReadyToRunLoadedImage * GetReadyToRunImage(); PTR_READYTORUN_IMPORT_SECTION GetImportSections(COUNT_T *pCount); PTR_READYTORUN_IMPORT_SECTION GetImportSectionFromIndex(COUNT_T index); PTR_READYTORUN_IMPORT_SECTION GetImportSectionForRVA(RVA rva); @@ -1490,7 +1490,7 @@ class Module : public ModuleBase BOOL FixupDelayListAux(TADDR pFixupList, Ptr pThis, FixupNativeEntryCallback pfnCB, PTR_READYTORUN_IMPORT_SECTION pImportSections, COUNT_T nImportSections, - PEDecoder * pNativeImage, BOOL mayUsePrecompiledPInvokeMethods = TRUE); + ReadyToRunLoadedImage * pNativeImage, BOOL mayUsePrecompiledPInvokeMethods = TRUE); void RunEagerFixups(); void RunEagerFixupsUnlocked(); diff --git a/src/coreclr/vm/ceeload.inl b/src/coreclr/vm/ceeload.inl index fe7ad7c7a9a09f..9989c3e5cf209b 100644 --- a/src/coreclr/vm/ceeload.inl +++ b/src/coreclr/vm/ceeload.inl @@ -354,7 +354,7 @@ template BOOL Module::FixupDelayListAux(TADDR pFixupList, Ptr pThis, FixupNativeEntryCallback pfnCB, PTR_READYTORUN_IMPORT_SECTION pImportSections, COUNT_T nImportSections, - PEDecoder * pNativeImage, BOOL mayUsePrecompiledPInvokeMethods) + ReadyToRunLoadedImage * pNativeImage, BOOL mayUsePrecompiledPInvokeMethods) { CONTRACTL { diff --git a/src/coreclr/vm/codeman.cpp b/src/coreclr/vm/codeman.cpp index 3fe0aaf192bb89..9360c8ce3f737d 100644 --- a/src/coreclr/vm/codeman.cpp +++ b/src/coreclr/vm/codeman.cpp @@ -6289,7 +6289,7 @@ unsigned ReadyToRunJitManager::InitializeEHEnumeration(const METHODTOKEN& Method if (pExceptionInfoDir == NULL) return 0; - PEImageLayout * pLayout = pReadyToRunInfo->GetImage(); + ReadyToRunLoadedImage * pLayout = pReadyToRunInfo->GetImage(); PTR_CORCOMPILE_EXCEPTION_LOOKUP_TABLE pExceptionLookupTable = dac_cast(pLayout->GetRvaData(pExceptionInfoDir->VirtualAddress)); diff --git a/src/coreclr/vm/frames.cpp b/src/coreclr/vm/frames.cpp index f879ea0b8f8421..49f03d4b0fe545 100644 --- a/src/coreclr/vm/frames.cpp +++ b/src/coreclr/vm/frames.cpp @@ -840,7 +840,7 @@ static PTR_BYTE FindGCRefMap(PTR_Module pZapModule, TADDR ptr) { LIMITED_METHOD_DAC_CONTRACT; - PEImageLayout *pNativeImage = pZapModule->GetReadyToRunImage(); + ReadyToRunLoadedImage *pNativeImage = pZapModule->GetReadyToRunImage(); RVA rva = pNativeImage->GetDataRva(ptr); diff --git a/src/coreclr/vm/nativeimage.cpp b/src/coreclr/vm/nativeimage.cpp index d0f30a7f34d32c..175ed954e47a08 100644 --- a/src/coreclr/vm/nativeimage.cpp +++ b/src/coreclr/vm/nativeimage.cpp @@ -41,7 +41,7 @@ NativeImageIndexTraits::count_t NativeImageIndexTraits::Hash(LPCUTF8 a) return SString(SString::Utf8Literal, a).HashCaseInsensitive(); } -NativeImage::NativeImage(AssemblyBinder *pAssemblyBinder, PEImageLayout *pImageLayout, LPCUTF8 imageFileName) +NativeImage::NativeImage(AssemblyBinder *pAssemblyBinder, ReadyToRunLoadedImage *pImageLayout, LPCUTF8 imageFileName) : m_eagerFixupsLock(CrstNativeImageEagerFixups) { CONTRACTL @@ -64,7 +64,7 @@ void NativeImage::Initialize(READYTORUN_HEADER *pHeader, LoaderAllocator *pLoade { LoaderHeap *pHeap = pLoaderAllocator->GetHighFrequencyHeap(); - m_pReadyToRunInfo = new ReadyToRunInfo(/*pModule*/ NULL, pLoaderAllocator, m_pImageLayout, pHeader, this, pamTracker); + m_pReadyToRunInfo = new ReadyToRunInfo(/*pModule*/ NULL, pLoaderAllocator, pHeader, this, m_pImageLayout, pamTracker); m_pComponentAssemblies = m_pReadyToRunInfo->FindSection(ReadyToRunSectionType::ComponentAssemblies); m_componentAssemblyCount = m_pComponentAssemblies->Size / sizeof(READYTORUN_COMPONENT_ASSEMBLIES_ENTRY); @@ -236,7 +236,14 @@ NativeImage *NativeImage::Open( { COMPlusThrowHR(COR_E_BADIMAGEFORMAT); } - NewHolder image = new NativeImage(pAssemblyBinder, peLoadedImage.Extract(), nativeImageFileName); + + NewHolder peLoadedImageHolder = new ReadyToRunLoadedImage( + (TADDR)peLoadedImage->GetBase(), + peLoadedImage->GetVirtualSize(), + peLoadedImage.Extract(), + [](void* img) { delete (PEImageLayout*)img; }); + + NewHolder image = new NativeImage(pAssemblyBinder, peLoadedImageHolder.Extract(), nativeImageFileName); AllocMemTracker amTracker; image->Initialize(pHeader, pLoaderAllocator, &amTracker); pExistingImage = AppDomain::GetCurrentDomain()->SetNativeImage(nativeImageFileName, image); diff --git a/src/coreclr/vm/nativeimage.h b/src/coreclr/vm/nativeimage.h index 722a8f1aa61688..b5511e5a930077 100644 --- a/src/coreclr/vm/nativeimage.h +++ b/src/coreclr/vm/nativeimage.h @@ -12,10 +12,10 @@ struct AssemblyNameIndex { LPCUTF8 Name; int32_t Index; - + AssemblyNameIndex() : Name(NULL), Index(-1) {} AssemblyNameIndex(LPCUTF8 name, int32_t index) : Name(name), Index(index) {} - + static AssemblyNameIndex GetNull() { return AssemblyNameIndex(); } bool IsNull() const { return Index < 0; } }; @@ -57,6 +57,7 @@ class NativeImageIndexTraits : public NoRemoveSHashTraits m_assemblySimpleNameToIndexMap; - + Crst m_eagerFixupsLock; bool m_eagerFixupsHaveRun; bool m_readyToRunCodeDisabled; private: - NativeImage(AssemblyBinder *pAssemblyBinder, PEImageLayout *peImageLayout, LPCUTF8 imageFileName); + NativeImage(AssemblyBinder *pAssemblyBinder, ReadyToRunLoadedImage *peImageLayout, LPCUTF8 imageFileName); protected: void Initialize(READYTORUN_HEADER *header, LoaderAllocator *loaderAllocator, AllocMemTracker *pamTracker); @@ -125,7 +126,7 @@ class NativeImage AssemblyBinder *GetAssemblyBinder() const { return m_pAssemblyBinder; } Assembly *LoadManifestAssembly(uint32_t rowid, Assembly *pParentAssembly); - + PTR_READYTORUN_CORE_HEADER GetComponentAssemblyHeader(LPCUTF8 assemblySimpleName); void CheckAssemblyMvid(Assembly *assembly) const; diff --git a/src/coreclr/vm/pgo.cpp b/src/coreclr/vm/pgo.cpp index eb3da3107c731e..40a8882baaffe8 100644 --- a/src/coreclr/vm/pgo.cpp +++ b/src/coreclr/vm/pgo.cpp @@ -1002,13 +1002,13 @@ class R2RInstrumentationDataReader { ReadyToRunInfo *m_pReadyToRunInfo; Module* m_pModule; - PEDecoder* m_pNativeImage; + ReadyToRunLoadedImage* m_pNativeImage; public: StackSArray schemaArray; StackSArray instrumentationData; - R2RInstrumentationDataReader(ReadyToRunInfo *pReadyToRunInfo, Module* pModule, PEDecoder* pNativeImage) : + R2RInstrumentationDataReader(ReadyToRunInfo *pReadyToRunInfo, Module* pModule, ReadyToRunLoadedImage* pNativeImage) : m_pReadyToRunInfo(pReadyToRunInfo), m_pModule(pModule), m_pNativeImage(pNativeImage) @@ -1103,7 +1103,7 @@ class R2RInstrumentationDataReader HRESULT PgoManager::getPgoInstrumentationResultsFromR2RFormat(ReadyToRunInfo *pReadyToRunInfo, Module* pModule, - PEDecoder* pNativeImage, + ReadyToRunLoadedImage* pNativeImage, BYTE* pR2RFormatData, size_t pR2RFormatDataMaxSize, BYTE** pAllocatedData, diff --git a/src/coreclr/vm/pgo.h b/src/coreclr/vm/pgo.h index c9d5f8975fe3c1..8a487dc315b407 100644 --- a/src/coreclr/vm/pgo.h +++ b/src/coreclr/vm/pgo.h @@ -7,6 +7,7 @@ #include "shash.h" class ReadyToRunInfo; +class ReadyToRunLoadedImage; // PgoManager handles in-process and out of band profile data for jitted code. class PgoManager @@ -26,7 +27,7 @@ class PgoManager static HRESULT allocPgoInstrumentationBySchema(MethodDesc* pMD, ICorJitInfo::PgoInstrumentationSchema* pSchema, UINT32 countSchemaItems, BYTE** pInstrumentationData); static HRESULT getPgoInstrumentationResultsFromR2RFormat(ReadyToRunInfo *pReadyToRunInfo, Module* pModule, - PEDecoder* pNativeImage, + ReadyToRunLoadedImage* pNativeImage, BYTE* pR2RFormatData, size_t pR2RFormatDataMaxSize, BYTE** pAllocatedData, diff --git a/src/coreclr/vm/prestub.cpp b/src/coreclr/vm/prestub.cpp index fa63cb58f5da53..521e56588d1496 100644 --- a/src/coreclr/vm/prestub.cpp +++ b/src/coreclr/vm/prestub.cpp @@ -2604,7 +2604,7 @@ EXTERN_C PCODE STDCALL ExternalMethodFixupWorker(TransitionBlock * pTransitionBl { GCX_PREEMP_THREAD_EXISTS(CURRENT_THREAD); - PEImageLayout *pNativeImage = pModule->GetReadyToRunImage(); + ReadyToRunLoadedImage *pNativeImage = pModule->GetReadyToRunImage(); RVA rva = pNativeImage->GetDataRva(pIndirection); @@ -3216,7 +3216,7 @@ PCODE DynamicHelperFixup(TransitionBlock * pTransitionBlock, TADDR * pCell, DWOR { STANDARD_VM_CONTRACT; - PEImageLayout *pNativeImage = pModule->GetReadyToRunImage(); + ReadyToRunLoadedImage *pNativeImage = pModule->GetReadyToRunImage(); RVA rva = pNativeImage->GetDataRva((TADDR)pCell); diff --git a/src/coreclr/vm/readytoruninfo.cpp b/src/coreclr/vm/readytoruninfo.cpp index e9e68f9c1fb45f..42b7e010028323 100644 --- a/src/coreclr/vm/readytoruninfo.cpp +++ b/src/coreclr/vm/readytoruninfo.cpp @@ -63,7 +63,7 @@ ReadyToRunCoreInfo::ReadyToRunCoreInfo() { } -ReadyToRunCoreInfo::ReadyToRunCoreInfo(PEImageLayout* pLayout, READYTORUN_CORE_HEADER *pCoreHeader) +ReadyToRunCoreInfo::ReadyToRunCoreInfo(ReadyToRunLoadedImage* pLayout, READYTORUN_CORE_HEADER *pCoreHeader) : m_pLayout(pLayout), m_pCoreHeader(pCoreHeader), m_fForbidLoadILBodyFixups(false) { } @@ -625,7 +625,10 @@ PTR_ReadyToRunInfo ReadyToRunInfo::Initialize(Module * pModule, AllocMemTracker return NULL; } + LoaderHeap *pHeap = pModule->GetLoaderAllocator()->GetHighFrequencyHeap(); + NativeImage *nativeImage = NULL; + ReadyToRunLoadedImage* loadedImage = nullptr; if (isComponentAssembly) { nativeImage = AcquireCompositeImage(pModule, pLayout, pHeader); @@ -642,14 +645,14 @@ PTR_ReadyToRunInfo ReadyToRunInfo::Initialize(Module * pModule, AllocMemTracker DoLog("Ready to Run disabled - module already loaded in another assembly load context"); return NULL; } + void* pLoadedImageMemory = pamTracker->Track(pHeap->AllocMem((S_SIZE_T)sizeof(ReadyToRunLoadedImage))); + loadedImage = new (pLoadedImageMemory) ReadyToRunLoadedImage((TADDR)pLayout->GetBase(), pLayout->GetVirtualSize()); } - LoaderHeap *pHeap = pModule->GetLoaderAllocator()->GetHighFrequencyHeap(); void * pMemory = pamTracker->Track(pHeap->AllocMem((S_SIZE_T)sizeof(ReadyToRunInfo))); - DoLog("Ready to Run initialized successfully"); - return new (pMemory) ReadyToRunInfo(pModule, pModule->GetLoaderAllocator(), pLayout, pHeader, nativeImage, pamTracker); + return new (pMemory) ReadyToRunInfo(pModule, pModule->GetLoaderAllocator(), pHeader, nativeImage, loadedImage, pamTracker); } bool ReadyToRunInfo::IsNativeImageSharedBy(PTR_Module pModule1, PTR_Module pModule2) @@ -762,7 +765,7 @@ PTR_ReadyToRunInfo ReadyToRunInfo::ComputeAlternateGenericLocationForR2RCode(Met } } -ReadyToRunInfo::ReadyToRunInfo(Module * pModule, LoaderAllocator* pLoaderAllocator, PEImageLayout * pLayout, READYTORUN_HEADER * pHeader, NativeImage *pNativeImage, AllocMemTracker *pamTracker) +ReadyToRunInfo::ReadyToRunInfo(Module * pModule, LoaderAllocator* pLoaderAllocator, READYTORUN_HEADER * pHeader, NativeImage *pNativeImage, ReadyToRunLoadedImage * pLayout, AllocMemTracker *pamTracker) : m_pModule(pModule), m_pHeader(pHeader), m_pNativeImage(pModule != NULL ? pNativeImage: NULL), // m_pNativeImage is only set for composite image components, not the composite R2R info itself @@ -775,6 +778,9 @@ ReadyToRunInfo::ReadyToRunInfo(Module * pModule, LoaderAllocator* pLoaderAllocat if ((pNativeImage != NULL) && (pModule != NULL)) { + // We are intializing ReadyToRunInfo for a specific component assembly inside a composite R2R image. + // In this case, we don't use the R2R info in the PE image directly, so we don't need the native layout. + _ASSERT(pLayout == NULL); // In multi-assembly composite images, per assembly sections are stored next to their core headers. m_pCompositeInfo = pNativeImage->GetReadyToRunInfo(); m_pComposite = m_pCompositeInfo->GetComponentInfo(); @@ -784,6 +790,11 @@ ReadyToRunInfo::ReadyToRunInfo(Module * pModule, LoaderAllocator* pLoaderAllocat } else { + // We are in one of the two following cases: + // 1. Initializing ReadyToRunInfo for a single-assembly R2R image. + // 2. Initializing ReadyToRunInfo for the composite R2R image itself. + // In this case, we'll pull the ready to run image layout from pLayout. + _ASSERT(pLayout != NULL); m_pCompositeInfo = this; m_component = ReadyToRunCoreInfo(pLayout, &pHeader->CoreHeader); m_pComposite = &m_component; diff --git a/src/coreclr/vm/readytoruninfo.h b/src/coreclr/vm/readytoruninfo.h index 5b7d071c171eb9..9f58e81c736c93 100644 --- a/src/coreclr/vm/readytoruninfo.h +++ b/src/coreclr/vm/readytoruninfo.h @@ -20,25 +20,27 @@ typedef DPTR(struct READYTORUN_SECTION) PTR_READYTORUN_SECTION; class NativeImage; class PrepareCodeConfig; +class ReadyToRunLoadedImage; typedef DPTR(class ReadyToRunCoreInfo) PTR_ReadyToRunCoreInfo; +typedef DPTR(class ReadyToRunLoadedImage) PTR_ReadyToRunLoadedImage; class ReadyToRunCoreInfo { private: - PTR_PEImageLayout m_pLayout; + PTR_ReadyToRunLoadedImage m_pLayout; PTR_READYTORUN_CORE_HEADER m_pCoreHeader; Volatile m_fForbidLoadILBodyFixups; public: ReadyToRunCoreInfo(); - ReadyToRunCoreInfo(PEImageLayout * pLayout, READYTORUN_CORE_HEADER * pCoreHeader); + ReadyToRunCoreInfo(ReadyToRunLoadedImage * pLayout, READYTORUN_CORE_HEADER * pCoreHeader); - PTR_PEImageLayout GetLayout() const { return m_pLayout; } + PTR_ReadyToRunLoadedImage GetLayout() const { return m_pLayout; } IMAGE_DATA_DIRECTORY * FindSection(ReadyToRunSectionType type) const; void ForbidProcessMoreILBodyFixups() { m_fForbidLoadILBodyFixups = true; } bool IsForbidProcessMoreILBodyFixups() { return m_fForbidLoadILBodyFixups; } - PTR_PEImageLayout GetImage() const + PTR_ReadyToRunLoadedImage GetImage() const { LIMITED_METHOD_CONTRACT; return m_pLayout; @@ -144,7 +146,7 @@ class ReadyToRunInfo PTR_ReadyToRunInfo m_pNextR2RForUnrelatedCode; public: - ReadyToRunInfo(Module * pModule, LoaderAllocator* pLoaderAllocator, PEImageLayout * pLayout, READYTORUN_HEADER * pHeader, NativeImage * pNativeImage, AllocMemTracker *pamTracker); + ReadyToRunInfo(Module * pModule, LoaderAllocator* pLoaderAllocator, READYTORUN_HEADER * pHeader, NativeImage * pNativeImage, ReadyToRunLoadedImage * pLayout, AllocMemTracker *pamTracker); static PTR_ReadyToRunInfo ComputeAlternateGenericLocationForR2RCode(MethodDesc *pMethod); static PTR_ReadyToRunInfo GetUnrelatedR2RModules(); @@ -165,7 +167,7 @@ class ReadyToRunInfo PTR_NativeImage GetNativeImage() const { return m_pNativeImage; } - PTR_PEImageLayout GetImage() const { return m_pComposite->GetImage(); } + PTR_ReadyToRunLoadedImage GetImage() const { return m_pComposite->GetImage(); } IMAGE_DATA_DIRECTORY * FindSection(ReadyToRunSectionType type) const { return m_pComposite->FindSection(type); } PCODE GetEntryPoint(MethodDesc * pMD, PrepareCodeConfig* pConfig, BOOL fFixups); @@ -391,4 +393,64 @@ struct GenericDictionaryDynamicHelperStubData GenericHandleArgs *HandleArgs; }; +class ReadyToRunLoadedImage +{ + TADDR m_pImageBase; + uint32_t m_imageSize; + + void* m_pImageCleanupData; + + void(*m_pfnCleanup)(void*); + +public: + ReadyToRunLoadedImage(TADDR m_pImageBase, uint32_t imageSize) + : m_pImageBase(m_pImageBase), m_imageSize(imageSize), m_pImageCleanupData(nullptr), m_pfnCleanup(nullptr) + { + } + + ReadyToRunLoadedImage(TADDR m_pImageBase, uint32_t imageSize, void* pImageCleanupData, void(*pfnCleanup)(void*)) + : m_pImageBase(m_pImageBase), m_imageSize(imageSize), m_pImageCleanupData(pImageCleanupData), m_pfnCleanup(pfnCleanup) + { + } + + ReadyToRunLoadedImage(const ReadyToRunLoadedImage&) = delete; + ReadyToRunLoadedImage& operator=(const ReadyToRunLoadedImage&) = delete; + ReadyToRunLoadedImage(ReadyToRunLoadedImage&&) = delete; + ReadyToRunLoadedImage& operator=(ReadyToRunLoadedImage&&) = delete; + + ~ReadyToRunLoadedImage() + { + if (m_pfnCleanup) + m_pfnCleanup(m_pImageCleanupData); + } + + TADDR GetBase() const + { + return m_pImageBase; + } + + uint32_t GetVirtualSize() const + { + return m_imageSize; + } + + TADDR GetDirectoryData(IMAGE_DATA_DIRECTORY* pDir, uint32_t* pSize = nullptr) const + { + if (pSize != nullptr) + *pSize = pDir->Size; + return m_pImageBase + pDir->VirtualAddress; + } + + TADDR GetRvaData(RVA rva) const + { + return m_pImageBase + rva; + } + + RVA GetDataRva(TADDR data) const + { + _ASSERTE_MSG(data >= m_pImageBase && data < m_pImageBase + m_imageSize, "Data pointer is outside of loaded image."); + return (RVA)(data - m_pImageBase); + } +}; + #endif // _READYTORUNINFO_H_