From 77115c33ec4fb8688e4803cd8f76cd0fa4bff7d7 Mon Sep 17 00:00:00 2001 From: Elinor Fung Date: Fri, 28 Feb 2025 10:21:34 -0800 Subject: [PATCH] Allow R2R for images provided via external_assembly_probe (#112934) Allow R2R for images provided via `external_assembly_probe` This re-uses the existing mechanism from single-file with R2R, where we load the image by copying it. This is obviously inefficient, but allows a first version of functioning R2R for Android. --- src/coreclr/vm/peimagelayout.cpp | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/src/coreclr/vm/peimagelayout.cpp b/src/coreclr/vm/peimagelayout.cpp index 8d5f02b2671ebd..3ac813a6a25de5 100644 --- a/src/coreclr/vm/peimagelayout.cpp +++ b/src/coreclr/vm/peimagelayout.cpp @@ -19,6 +19,20 @@ extern "C" } #endif +static bool AllowR2RForImage(PEImage* pOwner) +{ + // Allow R2R for files + if (pOwner->IsFile()) + return true; + + // Allow R2R for externally provided images + INT64 size; + if (pOwner->GetExternalData(&size) != NULL && size > 0) + return true; + + return false; +} + #ifndef DACCESS_COMPILE PEImageLayout* PEImageLayout::CreateFromByteArray(PEImage* pOwner, const BYTE* array, COUNT_T size) { @@ -70,9 +84,11 @@ PEImageLayout* PEImageLayout::LoadConverted(PEImage* pOwner, bool disableMapping pFlat = (FlatImageLayout*)pOwner->GetFlatLayout(); pFlat->AddRef(); } - else if (pOwner->IsFile()) + else if (AllowR2RForImage(pOwner)) { + // We only expect to be converting images that aren't already opened in the R2R composite case pFlat = new FlatImageLayout(pOwner); + _ASSERTE(pFlat->HasReadyToRunHeader()); } if (pFlat == NULL || !pFlat->CheckILOnlyFormat()) @@ -88,9 +104,8 @@ PEImageLayout* PEImageLayout::LoadConverted(PEImage* pOwner, bool disableMapping _ASSERTE(!pOwner->IsFile() || !pFlat->HasReadyToRunHeader() || disableMapping); #endif - // ignore R2R if the image is not a file. - if ((pFlat->HasReadyToRunHeader() && pOwner->IsFile()) || - pFlat->HasWriteableSections()) + if ((pFlat->HasReadyToRunHeader() && AllowR2RForImage(pOwner)) + || pFlat->HasWriteableSections()) { return new ConvertedImageLayout(pFlat, disableMapping); } @@ -462,7 +477,7 @@ ConvertedImageLayout::ConvertedImageLayout(FlatImageLayout* source, bool disable IfFailThrow(Init(loadedImage)); - if (m_pOwner->IsFile() && IsNativeMachineFormat()) + if (AllowR2RForImage(m_pOwner) && IsNativeMachineFormat()) { // Do base relocation and exception hookup, if necessary. // otherwise R2R will be disabled for this image.