AcquiredBefore FuncPtrStubs ThreadStore SystemDomain
AcquiredAfter ReJITGlobalRequest
End
+
+Crst NativeImageEagerFixups
+End
CrstMUThunkHash = 88,
CrstNativeBinderInit = 89,
CrstNativeImageCache = 90,
- CrstNls = 91,
- CrstNotifyGdb = 92,
- CrstObjectList = 93,
- CrstOnEventManager = 94,
- CrstPatchEntryPoint = 95,
- CrstPEImage = 96,
- CrstPEImagePDBStream = 97,
- CrstPendingTypeLoadEntry = 98,
- CrstPinHandle = 99,
- CrstPinnedByrefValidation = 100,
- CrstProfilerGCRefDataFreeList = 101,
- CrstProfilingAPIStatus = 102,
- CrstPublisherCertificate = 103,
- CrstRCWCache = 104,
- CrstRCWCleanupList = 105,
- CrstRCWRefCache = 106,
- CrstReadyToRunEntryPointToMethodDescMap = 107,
- CrstReDacl = 108,
- CrstReflection = 109,
- CrstReJITGlobalRequest = 110,
- CrstRemoting = 111,
- CrstRetThunkCache = 112,
- CrstRWLock = 113,
- CrstSavedExceptionInfo = 114,
- CrstSaveModuleProfileData = 115,
- CrstSecurityStackwalkCache = 116,
- CrstSharedAssemblyCreate = 117,
- CrstSigConvert = 118,
- CrstSingleUseLock = 119,
- CrstSpecialStatics = 120,
- CrstSqmManager = 121,
- CrstStackSampler = 122,
- CrstStressLog = 123,
- CrstStrongName = 124,
- CrstStubCache = 125,
- CrstStubDispatchCache = 126,
- CrstStubUnwindInfoHeapSegments = 127,
- CrstSyncBlockCache = 128,
- CrstSyncHashLock = 129,
- CrstSystemBaseDomain = 130,
- CrstSystemDomain = 131,
- CrstSystemDomainDelayedUnloadList = 132,
- CrstThreadIdDispenser = 133,
- CrstThreadpoolEventCache = 134,
- CrstThreadpoolTimerQueue = 135,
- CrstThreadpoolWaitThreads = 136,
- CrstThreadpoolWorker = 137,
- CrstThreadStaticDataHashTable = 138,
- CrstThreadStore = 139,
- CrstTieredCompilation = 140,
- CrstTPMethodTable = 141,
- CrstTypeEquivalenceMap = 142,
- CrstTypeIDMap = 143,
- CrstUMEntryThunkCache = 144,
- CrstUMThunkHash = 145,
- CrstUniqueStack = 146,
- CrstUnresolvedClassLock = 147,
- CrstUnwindInfoTableLock = 148,
- CrstVSDIndirectionCellLock = 149,
- CrstWinRTFactoryCache = 150,
- CrstWrapperTemplate = 151,
- kNumberOfCrstTypes = 152
+ CrstNativeImageEagerFixups = 91,
+ CrstNls = 92,
+ CrstNotifyGdb = 93,
+ CrstObjectList = 94,
+ CrstOnEventManager = 95,
+ CrstPatchEntryPoint = 96,
+ CrstPEImage = 97,
+ CrstPEImagePDBStream = 98,
+ CrstPendingTypeLoadEntry = 99,
+ CrstPinHandle = 100,
+ CrstPinnedByrefValidation = 101,
+ CrstProfilerGCRefDataFreeList = 102,
+ CrstProfilingAPIStatus = 103,
+ CrstPublisherCertificate = 104,
+ CrstRCWCache = 105,
+ CrstRCWCleanupList = 106,
+ CrstRCWRefCache = 107,
+ CrstReadyToRunEntryPointToMethodDescMap = 108,
+ CrstReDacl = 109,
+ CrstReflection = 110,
+ CrstReJITGlobalRequest = 111,
+ CrstRemoting = 112,
+ CrstRetThunkCache = 113,
+ CrstRWLock = 114,
+ CrstSavedExceptionInfo = 115,
+ CrstSaveModuleProfileData = 116,
+ CrstSecurityStackwalkCache = 117,
+ CrstSharedAssemblyCreate = 118,
+ CrstSigConvert = 119,
+ CrstSingleUseLock = 120,
+ CrstSpecialStatics = 121,
+ CrstSqmManager = 122,
+ CrstStackSampler = 123,
+ CrstStressLog = 124,
+ CrstStrongName = 125,
+ CrstStubCache = 126,
+ CrstStubDispatchCache = 127,
+ CrstStubUnwindInfoHeapSegments = 128,
+ CrstSyncBlockCache = 129,
+ CrstSyncHashLock = 130,
+ CrstSystemBaseDomain = 131,
+ CrstSystemDomain = 132,
+ CrstSystemDomainDelayedUnloadList = 133,
+ CrstThreadIdDispenser = 134,
+ CrstThreadpoolEventCache = 135,
+ CrstThreadpoolTimerQueue = 136,
+ CrstThreadpoolWaitThreads = 137,
+ CrstThreadpoolWorker = 138,
+ CrstThreadStaticDataHashTable = 139,
+ CrstThreadStore = 140,
+ CrstTieredCompilation = 141,
+ CrstTPMethodTable = 142,
+ CrstTypeEquivalenceMap = 143,
+ CrstTypeIDMap = 144,
+ CrstUMEntryThunkCache = 145,
+ CrstUMThunkHash = 146,
+ CrstUniqueStack = 147,
+ CrstUnresolvedClassLock = 148,
+ CrstUnwindInfoTableLock = 149,
+ CrstVSDIndirectionCellLock = 150,
+ CrstWinRTFactoryCache = 151,
+ CrstWrapperTemplate = 152,
+ kNumberOfCrstTypes = 153
};
#endif // __CRST_TYPES_INCLUDED
// An array mapping CrstType to level.
int g_rgCrstLevelMap[] =
{
- 9, // CrstAllowedFiles
- 9, // CrstAppDomainCache
- 14, // CrstAppDomainHandleTable
- 0, // CrstArgBasedStubCache
- 0, // CrstAssemblyDependencyGraph
- 0, // CrstAssemblyIdentityCache
- 0, // CrstAssemblyList
- 7, // CrstAssemblyLoader
- 3, // CrstAvailableClass
- 4, // CrstAvailableParamTypes
- 7, // CrstBaseDomain
- -1, // CrstCCompRC
- 9, // CrstCer
- 13, // CrstClassFactInfoHash
- 8, // CrstClassInit
- -1, // CrstClrNotification
- 0, // CrstCLRPrivBinderMaps
- 3, // CrstCLRPrivBinderMapsAdd
- 6, // CrstCodeFragmentHeap
- 10, // CrstCodeVersioning
- 0, // CrstCOMCallWrapper
- 4, // CrstCOMWrapperCache
- 0, // CrstConnectionNameTable
- 17, // CrstContexts
- 0, // CrstCrstCLRPrivBinderLocalWinMDPath
- 7, // CrstCSPCache
- 3, // CrstDataTest1
- 0, // CrstDataTest2
- 0, // CrstDbgTransport
- 0, // CrstDeadlockDetection
- -1, // CrstDebuggerController
- 3, // CrstDebuggerFavorLock
- 0, // CrstDebuggerHeapExecMemLock
- 0, // CrstDebuggerHeapLock
- 4, // CrstDebuggerJitInfo
- 11, // CrstDebuggerMutex
- 0, // CrstDelegateToFPtrHash
- 16, // CrstDomainLocalBlock
- 0, // CrstDynamicIL
- 3, // CrstDynamicMT
- 3, // CrstDynLinkZapItems
- 7, // CrstEtwTypeLogHash
- 18, // CrstEventPipe
- 0, // CrstEventStore
- 0, // CrstException
- 7, // CrstExecuteManLock
- 0, // CrstExecuteManRangeLock
- 3, // CrstFCall
- 7, // CrstFriendAccessCache
- 7, // CrstFuncPtrStubs
- 5, // CrstFusionAppCtx
- 11, // CrstGCCover
- 0, // CrstGCMemoryPressure
- 13, // CrstGlobalStrLiteralMap
- 1, // CrstHandleTable
- 0, // CrstHostAssemblyMap
- 3, // CrstHostAssemblyMapAdd
- 0, // CrstIbcProfile
- 9, // CrstIJWFixupData
- 0, // CrstIJWHash
- 7, // CrstILStubGen
- 3, // CrstInlineTrackingMap
- 17, // CrstInstMethodHashTable
- 0, // CrstInterfaceVTableMap
- 18, // CrstInterop
- 4, // CrstInteropData
- 13, // CrstIOThreadpoolWorker
- 0, // CrstIsJMCMethod
- 7, // CrstISymUnmanagedReader
- 8, // CrstJit
- 0, // CrstJitGenericHandleCache
- 16, // CrstJitInlineTrackingMap
- -1, // CrstJitPerf
- 6, // CrstJumpStubCache
- 0, // CrstLeafLock
- -1, // CrstListLock
- 15, // CrstLoaderAllocator
- 16, // CrstLoaderAllocatorReferences
- 0, // CrstLoaderHeap
- 0, // CrstMda
- -1, // CrstMetadataTracker
- 14, // CrstMethodDescBackpatchInfoTracker
- 0, // CrstModIntPairList
- 4, // CrstModule
- 15, // CrstModuleFixup
- 3, // CrstModuleLookupTable
- 0, // CrstMulticoreJitHash
- 13, // CrstMulticoreJitManager
- 0, // CrstMUThunkHash
- -1, // CrstNativeBinderInit
- -1, // CrstNativeImageCache
- 0, // CrstNls
- 0, // CrstNotifyGdb
- 2, // CrstObjectList
- 0, // CrstOnEventManager
- 0, // CrstPatchEntryPoint
- 4, // CrstPEImage
- 0, // CrstPEImagePDBStream
- 19, // CrstPendingTypeLoadEntry
- 0, // CrstPinHandle
- 0, // CrstPinnedByrefValidation
- 0, // CrstProfilerGCRefDataFreeList
- 0, // CrstProfilingAPIStatus
- 0, // CrstPublisherCertificate
- 3, // CrstRCWCache
- 0, // CrstRCWCleanupList
- 3, // CrstRCWRefCache
- 4, // CrstReadyToRunEntryPointToMethodDescMap
- 0, // CrstReDacl
- 9, // CrstReflection
- 17, // CrstReJITGlobalRequest
- 20, // CrstRemoting
- 3, // CrstRetThunkCache
- 0, // CrstRWLock
- 3, // CrstSavedExceptionInfo
- 0, // CrstSaveModuleProfileData
- 0, // CrstSecurityStackwalkCache
- 4, // CrstSharedAssemblyCreate
- 3, // CrstSigConvert
- 5, // CrstSingleUseLock
- 0, // CrstSpecialStatics
- 0, // CrstSqmManager
- 0, // CrstStackSampler
- -1, // CrstStressLog
- 0, // CrstStrongName
- 5, // CrstStubCache
- 0, // CrstStubDispatchCache
- 4, // CrstStubUnwindInfoHeapSegments
- 3, // CrstSyncBlockCache
- 0, // CrstSyncHashLock
- 4, // CrstSystemBaseDomain
- 13, // CrstSystemDomain
- 0, // CrstSystemDomainDelayedUnloadList
- 0, // CrstThreadIdDispenser
- 0, // CrstThreadpoolEventCache
- 7, // CrstThreadpoolTimerQueue
- 7, // CrstThreadpoolWaitThreads
- 13, // CrstThreadpoolWorker
- 4, // CrstThreadStaticDataHashTable
- 12, // CrstThreadStore
- 9, // CrstTieredCompilation
- 9, // CrstTPMethodTable
- 3, // CrstTypeEquivalenceMap
- 7, // CrstTypeIDMap
- 3, // CrstUMEntryThunkCache
- 0, // CrstUMThunkHash
- 3, // CrstUniqueStack
- 7, // CrstUnresolvedClassLock
- 3, // CrstUnwindInfoTableLock
- 3, // CrstVSDIndirectionCellLock
- 3, // CrstWinRTFactoryCache
- 3, // CrstWrapperTemplate
+ 9, // CrstAllowedFiles
+ 9, // CrstAppDomainCache
+ 14, // CrstAppDomainHandleTable
+ 0, // CrstArgBasedStubCache
+ 0, // CrstAssemblyDependencyGraph
+ 0, // CrstAssemblyIdentityCache
+ 0, // CrstAssemblyList
+ 7, // CrstAssemblyLoader
+ 3, // CrstAvailableClass
+ 4, // CrstAvailableParamTypes
+ 7, // CrstBaseDomain
+ -1, // CrstCCompRC
+ 9, // CrstCer
+ 13, // CrstClassFactInfoHash
+ 8, // CrstClassInit
+ -1, // CrstClrNotification
+ 0, // CrstCLRPrivBinderMaps
+ 3, // CrstCLRPrivBinderMapsAdd
+ 6, // CrstCodeFragmentHeap
+ 10, // CrstCodeVersioning
+ 0, // CrstCOMCallWrapper
+ 4, // CrstCOMWrapperCache
+ 0, // CrstConnectionNameTable
+ 17, // CrstContexts
+ 0, // CrstCrstCLRPrivBinderLocalWinMDPath
+ 7, // CrstCSPCache
+ 3, // CrstDataTest1
+ 0, // CrstDataTest2
+ 0, // CrstDbgTransport
+ 0, // CrstDeadlockDetection
+ -1, // CrstDebuggerController
+ 3, // CrstDebuggerFavorLock
+ 0, // CrstDebuggerHeapExecMemLock
+ 0, // CrstDebuggerHeapLock
+ 4, // CrstDebuggerJitInfo
+ 11, // CrstDebuggerMutex
+ 0, // CrstDelegateToFPtrHash
+ 16, // CrstDomainLocalBlock
+ 0, // CrstDynamicIL
+ 3, // CrstDynamicMT
+ 3, // CrstDynLinkZapItems
+ 7, // CrstEtwTypeLogHash
+ 18, // CrstEventPipe
+ 0, // CrstEventStore
+ 0, // CrstException
+ 7, // CrstExecuteManLock
+ 0, // CrstExecuteManRangeLock
+ 3, // CrstFCall
+ 7, // CrstFriendAccessCache
+ 7, // CrstFuncPtrStubs
+ 5, // CrstFusionAppCtx
+ 11, // CrstGCCover
+ 0, // CrstGCMemoryPressure
+ 13, // CrstGlobalStrLiteralMap
+ 1, // CrstHandleTable
+ 0, // CrstHostAssemblyMap
+ 3, // CrstHostAssemblyMapAdd
+ 0, // CrstIbcProfile
+ 9, // CrstIJWFixupData
+ 0, // CrstIJWHash
+ 7, // CrstILStubGen
+ 3, // CrstInlineTrackingMap
+ 17, // CrstInstMethodHashTable
+ 0, // CrstInterfaceVTableMap
+ 18, // CrstInterop
+ 4, // CrstInteropData
+ 13, // CrstIOThreadpoolWorker
+ 0, // CrstIsJMCMethod
+ 7, // CrstISymUnmanagedReader
+ 8, // CrstJit
+ 0, // CrstJitGenericHandleCache
+ 16, // CrstJitInlineTrackingMap
+ -1, // CrstJitPerf
+ 6, // CrstJumpStubCache
+ 0, // CrstLeafLock
+ -1, // CrstListLock
+ 15, // CrstLoaderAllocator
+ 16, // CrstLoaderAllocatorReferences
+ 0, // CrstLoaderHeap
+ 0, // CrstMda
+ -1, // CrstMetadataTracker
+ 14, // CrstMethodDescBackpatchInfoTracker
+ 0, // CrstModIntPairList
+ 4, // CrstModule
+ 15, // CrstModuleFixup
+ 3, // CrstModuleLookupTable
+ 0, // CrstMulticoreJitHash
+ 13, // CrstMulticoreJitManager
+ 0, // CrstMUThunkHash
+ -1, // CrstNativeBinderInit
+ -1, // CrstNativeImageCache
+ 0, // CrstNativeImageEagerFixups
+ 0, // CrstNls
+ 0, // CrstNotifyGdb
+ 2, // CrstObjectList
+ 0, // CrstOnEventManager
+ 0, // CrstPatchEntryPoint
+ 4, // CrstPEImage
+ 0, // CrstPEImagePDBStream
+ 19, // CrstPendingTypeLoadEntry
+ 0, // CrstPinHandle
+ 0, // CrstPinnedByrefValidation
+ 0, // CrstProfilerGCRefDataFreeList
+ 0, // CrstProfilingAPIStatus
+ 0, // CrstPublisherCertificate
+ 3, // CrstRCWCache
+ 0, // CrstRCWCleanupList
+ 3, // CrstRCWRefCache
+ 4, // CrstReadyToRunEntryPointToMethodDescMap
+ 0, // CrstReDacl
+ 9, // CrstReflection
+ 17, // CrstReJITGlobalRequest
+ 20, // CrstRemoting
+ 3, // CrstRetThunkCache
+ 0, // CrstRWLock
+ 3, // CrstSavedExceptionInfo
+ 0, // CrstSaveModuleProfileData
+ 0, // CrstSecurityStackwalkCache
+ 4, // CrstSharedAssemblyCreate
+ 3, // CrstSigConvert
+ 5, // CrstSingleUseLock
+ 0, // CrstSpecialStatics
+ 0, // CrstSqmManager
+ 0, // CrstStackSampler
+ -1, // CrstStressLog
+ 0, // CrstStrongName
+ 5, // CrstStubCache
+ 0, // CrstStubDispatchCache
+ 4, // CrstStubUnwindInfoHeapSegments
+ 3, // CrstSyncBlockCache
+ 0, // CrstSyncHashLock
+ 4, // CrstSystemBaseDomain
+ 13, // CrstSystemDomain
+ 0, // CrstSystemDomainDelayedUnloadList
+ 0, // CrstThreadIdDispenser
+ 0, // CrstThreadpoolEventCache
+ 7, // CrstThreadpoolTimerQueue
+ 7, // CrstThreadpoolWaitThreads
+ 13, // CrstThreadpoolWorker
+ 4, // CrstThreadStaticDataHashTable
+ 12, // CrstThreadStore
+ 9, // CrstTieredCompilation
+ 9, // CrstTPMethodTable
+ 3, // CrstTypeEquivalenceMap
+ 7, // CrstTypeIDMap
+ 3, // CrstUMEntryThunkCache
+ 0, // CrstUMThunkHash
+ 3, // CrstUniqueStack
+ 7, // CrstUnresolvedClassLock
+ 3, // CrstUnwindInfoTableLock
+ 3, // CrstVSDIndirectionCellLock
+ 3, // CrstWinRTFactoryCache
+ 3, // CrstWrapperTemplate
};
// An array mapping CrstType to a stringized name.
"CrstMUThunkHash",
"CrstNativeBinderInit",
"CrstNativeImageCache",
+ "CrstNativeImageEagerFixups",
"CrstNls",
"CrstNotifyGdb",
"CrstObjectList",
#include "corcompile.h"
#include "readytorun.h"
+typedef DPTR(struct READYTORUN_CORE_HEADER) PTR_READYTORUN_CORE_HEADER;
typedef DPTR(struct READYTORUN_HEADER) PTR_READYTORUN_HEADER;
typedef DPTR(struct READYTORUN_SECTION) PTR_READYTORUN_SECTION;
TADDR GetVirtualSectionsTable(COUNT_T *pSize = NULL) const;
#endif // FEATURE_PREJIT
+ BOOL IsComponentAssembly() const;
BOOL HasReadyToRunHeader() const;
READYTORUN_HEADER *GetReadyToRunHeader() const;
BOOL HasNativeEntryPoint() const;
void *GetNativeEntryPoint() const;
+ // Look up a named symbol in the export directory
+ void *GetExport(LPCSTR exportName) const;
+
#ifdef _DEBUG
// Stress mode for relocations
static BOOL GetForceRelocs();
dwMachine = IMAGE_FILE_MACHINE_NATIVE;
}
- if ((GetReadyToRunHeader()->Flags & READYTORUN_FLAG_PLATFORM_NEUTRAL_SOURCE) != 0)
+ if ((GetReadyToRunHeader()->CoreHeader.Flags & READYTORUN_FLAG_PLATFORM_NEUTRAL_SOURCE) != 0)
{
// Supply the original PEKind/Machine to the assembly binder to make the full assembly name look like the original
dwKind = peILonly;
return ((dwKind & (peILonly | pe32Plus | pe32BitRequired)) == peILonly) && (dwMachine == IMAGE_FILE_MACHINE_I386);
}
+inline BOOL PEDecoder::IsComponentAssembly() const
+{
+ CONTRACTL
+ {
+ INSTANCE_CHECK;
+ NOTHROW;
+ GC_NOTRIGGER;
+ CANNOT_TAKE_LOCK;
+ SUPPORTS_DAC;
+ }
+ CONTRACTL_END;
+
+ return HasReadyToRunHeader() && (m_pReadyToRunHeader->CoreHeader.Flags & READYTORUN_FLAG_COMPONENT) != 0;
+}
+
inline BOOL PEDecoder::HasReadyToRunHeader() const
{
CONTRACTL
// R2R Version 3.0 changes calling conventions to correctly handle explicit structures to spec.
// R2R 3.0 is not backward compatible with 2.x.
-struct READYTORUN_HEADER
+struct READYTORUN_CORE_HEADER
{
- DWORD Signature; // READYTORUN_SIGNATURE
- USHORT MajorVersion; // READYTORUN_VERSION_XXX
- USHORT MinorVersion;
-
DWORD Flags; // READYTORUN_FLAG_XXX
DWORD NumberOfSections;
// READYTORUN_SECTION Sections[];
};
+struct READYTORUN_HEADER
+{
+ DWORD Signature; // READYTORUN_SIGNATURE
+ USHORT MajorVersion; // READYTORUN_VERSION_XXX
+ USHORT MinorVersion;
+
+ READYTORUN_CORE_HEADER CoreHeader;
+};
+
+struct READYTORUN_COMPONENT_ASSEMBLIES_ENTRY
+{
+ IMAGE_DATA_DIRECTORY CorHeader;
+ IMAGE_DATA_DIRECTORY ReadyToRunCoreHeader;
+};
+
enum ReadyToRunFlag
{
READYTORUN_FLAG_PLATFORM_NEUTRAL_SOURCE = 0x00000001, // Set if the original IL assembly was platform-neutral
READYTORUN_FLAG_SKIP_TYPE_VALIDATION = 0x00000002, // Set of methods with native code was determined using profile data
READYTORUN_FLAG_PARTIAL = 0x00000004,
- READYTORUN_FLAG_NONSHARED_PINVOKE_STUBS = 0x00000008 // PInvoke stubs compiled into image are non-shareable (no secret parameter)
+ READYTORUN_FLAG_NONSHARED_PINVOKE_STUBS = 0x00000008, // PInvoke stubs compiled into image are non-shareable (no secret parameter)
+ READYTORUN_FLAG_EMBEDDED_MSIL = 0x00000010, // MSIL is embedded in the composite R2R executable
+ READYTORUN_FLAG_COMPONENT = 0x00000020, // This is the header describing a component assembly of composite R2R
};
enum class ReadyToRunSectionType : uint32_t
ManifestMetadata = 112, // Added in V2.3
AttributePresence = 113, // Added in V3.1
InliningInfo2 = 114, // Added in V4.1
+ ComponentAssemblies = 115, // Added in V4.1
+ OwnerCompositeExecutable = 116, // Added in V4.1
// If you add a new section consider whether it is a breaking or non-breaking change.
// Usually it is non-breaking, but if it is preferable to have older runtimes fail
{
"coreclr",
"clrjit",
- "mscorrc",
"mscordaccore",
"mscordbi",
};
+ private static string[] s_runtimeWindowsOnlyLibraries =
+ {
+ "mscorrc",
+ };
+
private List<string> _compilationInputFiles;
private List<string> _mainExecutables;
{
passThroughFiles.Add(Path.Combine(options.CoreRootDirectory.FullName, exe.AppendOSExeSuffix()));
}
+ string libraryPrefix = (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "" : "lib");
foreach (string lib in s_runtimeLibraries)
{
- passThroughFiles.Add(Path.Combine(options.CoreRootDirectory.FullName, lib.AppendOSDllSuffix()));
+ passThroughFiles.Add(Path.Combine(options.CoreRootDirectory.FullName, (libraryPrefix + lib).AppendOSDllSuffix()));
+ }
+ if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
+ {
+ foreach (string lib in s_runtimeWindowsOnlyLibraries)
+ {
+ passThroughFiles.Add(Path.Combine(options.CoreRootDirectory.FullName, lib.AppendOSDllSuffix()));
+ }
}
}
_moduleIdToAssemblyNameMap = new Dictionary<int, AssemblyName>();
_signatureEmitters = new List<ISignatureEmitter>();
_nodeFactory = nodeFactory;
+ _nextModuleId = 1;
if (!_nodeFactory.CompilationModuleGroup.IsCompositeBuildMode)
{
MetadataReader mdReader = _nodeFactory.CompilationModuleGroup.CompilationModuleSet.Single().MetadataReader;
- _assemblyRefCount = mdReader.GetTableRowCount(TableIndex.AssemblyRef);
- for (int assemblyRefIndex = 1; assemblyRefIndex <= _assemblyRefCount; assemblyRefIndex++)
+ _assemblyRefCount = mdReader.GetTableRowCount(TableIndex.AssemblyRef) + 1;
+ for (int assemblyRefIndex = 1; assemblyRefIndex < _assemblyRefCount; assemblyRefIndex++)
{
AssemblyReferenceHandle assemblyRefHandle = MetadataTokens.AssemblyReferenceHandle(assemblyRefIndex);
AssemblyReference assemblyRef = mdReader.GetAssemblyReference(assemblyRefHandle);
string assemblyName = mdReader.GetString(assemblyRef.Name);
_assemblyRefToModuleIdMap[assemblyName] = assemblyRefIndex;
}
- }
- // AssemblyRefCount + 1 corresponds to ROWID 0 in the manifest metadata
- _nextModuleId = _assemblyRefCount + 2;
+ // AssemblyRefCount + 1 corresponds to ROWID 0 in the manifest metadata
+ _nextModuleId += _assemblyRefCount;
+ }
if (_nodeFactory.CompilationModuleGroup.IsCompositeBuildMode)
{
// Fill in entries for all input modules right away to make sure they have parallel indices
- int nextExpectedId = 2;
+ int nextExpectedId = 1;
foreach (EcmaModule inputModule in _nodeFactory.CompilationModuleGroup.CompilationModuleSet)
{
int acquiredId = ModuleToIndexInternal(inputModule);
_assemblyRefToModuleIdMap.Add(assemblyName.Name, assemblyRefIndex);
}
- if ((assemblyRefIndex >= _assemblyRefCount + 2) && !_moduleIdToAssemblyNameMap.ContainsKey(assemblyRefIndex))
+ if (assemblyRefIndex >= _assemblyRefCount && !_moduleIdToAssemblyNameMap.ContainsKey(assemblyRefIndex))
{
if (_emissionCompleted)
{
public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
{
ObjectDataBuilder builder = new ObjectDataBuilder(factory, relocsOnly);
- builder.RequireInitialPointerAlignment();
builder.AddSymbol(this);
builder.EmitBytes(Encoding.UTF8.GetBytes(_ownerExecutableName));
+ builder.EmitByte(0); // zero string terminator
return builder.ToObjectData();
}
}
throw new BadImageFormatException("The file is not a ReadyToRun image");
}
+ Debug.Assert(!Composite);
_assemblyCache.Add(metadata);
DirectoryEntry r2rHeaderDirectory = PEReader.PEHeaders.CorHeader.ManagedNativeHeaderDirectory;
{
if (ReadyToRunAssemblyHeaders[assemblyIndex].Sections.TryGetValue(ReadyToRunSectionType.MethodDefEntryPoints, out methodEntryPointSection))
{
- ParseMethodDefEntrypointsSection(methodEntryPointSection, OpenReferenceAssembly(assemblyIndex + 2), isEntryPoint);
+ ParseMethodDefEntrypointsSection(methodEntryPointSection, OpenReferenceAssembly(assemblyIndex + 1), isEntryPoint);
}
}
}
if (_readyToRunAssemblyHeaders[assemblyIndex].Sections.TryGetValue(
ReadyToRunSectionType.AvailableTypes, out availableTypesSection))
{
- ParseAvailableTypesSection(availableTypesSection, OpenReferenceAssembly(assemblyIndex + 2));
+ ParseAvailableTypesSection(availableTypesSection, OpenReferenceAssembly(assemblyIndex + 1));
}
}
}
{
Debug.Assert(refAsmIndex != 0);
- int assemblyRefCount = (_composite ? 0 : _assemblyCache[0].GetTableRowCount(TableIndex.AssemblyRef));
+ int assemblyRefCount = (_composite ? 0 : _assemblyCache[0].GetTableRowCount(TableIndex.AssemblyRef) + 1);
AssemblyReferenceHandle assemblyReferenceHandle;
- if (refAsmIndex <= assemblyRefCount)
+ if (refAsmIndex < assemblyRefCount)
{
metadataReader = _assemblyCache[0];
assemblyReferenceHandle = MetadataTokens.AssemblyReferenceHandle(refAsmIndex);
else
{
metadataReader = ManifestReader;
- assemblyReferenceHandle = ManifestReferences[refAsmIndex - assemblyRefCount - 2];
+ assemblyReferenceHandle = ManifestReferences[refAsmIndex - assemblyRefCount - 1];
}
return assemblyReferenceHandle;
if (!_r2r.Composite)
{
MetadataReader globalReader = _r2r.GetGlobalMetadataReader();
- assemblyRefCount = globalReader.GetTableRowCount(TableIndex.AssemblyRef);
+ assemblyRefCount = globalReader.GetTableRowCount(TableIndex.AssemblyRef) + 1;
_writer.WriteLine($"MSIL AssemblyRef's ({assemblyRefCount} entries):");
for (int assemblyRefIndex = 1; assemblyRefIndex <= assemblyRefCount; assemblyRefIndex++)
{
int manifestAsmIndex = 0;
foreach (string manifestReferenceAssembly in _r2r.ManifestReferenceAssemblies.OrderBy(kvp => kvp.Value).Select(kvp => kvp.Key))
{
- _writer.WriteLine($"[ID 0x{manifestAsmIndex + assemblyRefCount + 2:X2}]: {manifestReferenceAssembly}");
+ _writer.WriteLine($"[ID 0x{manifestAsmIndex + assemblyRefCount + 1:X2}]: {manifestReferenceAssembly}");
manifestAsmIndex++;
}
break;
case ReadyToRunSectionType.OwnerCompositeExecutable:
int oceOffset = _r2r.GetOffset(section.RelativeVirtualAddress);
Decoder decoder = Encoding.UTF8.GetDecoder();
- int charLength = decoder.GetCharCount(_r2r.Image, oceOffset, section.Size);
+ int charLength = decoder.GetCharCount(_r2r.Image, oceOffset, section.Size - 1); // exclude the zero terminator
char[] charArray = new char[charLength];
decoder.GetChars(_r2r.Image, oceOffset, section.Size, charArray, 0, flush: true);
string ownerCompositeExecutable = new string(charArray);
PTR_READYTORUN_HEADER pHeader = PTR_READYTORUN_HEADER((TADDR)GetDirectoryData(pDir));
if (pHeader->Signature == READYTORUN_SIGNATURE)
{
- const_cast<PEDecoder *>(this)->m_pReadyToRunHeader = pHeader;
+ const_cast<PEDecoder*>(this)->m_pReadyToRunHeader = pHeader;
return pHeader;
}
}
return NULL;
}
+#ifndef DACCESS_COMPILE
+void *PEDecoder::GetExport(LPCSTR exportName) const
+{
+ // Get the export directory entry
+ PIMAGE_DATA_DIRECTORY pExportDirectoryEntry = GetDirectoryEntry(IMAGE_DIRECTORY_ENTRY_EXPORT);
+ if (pExportDirectoryEntry->VirtualAddress == 0 || pExportDirectoryEntry->Size == 0)
+ {
+ return NULL;
+ }
+
+ uint8_t *imageBase = (uint8_t *)GetBase();
+ const IMAGE_EXPORT_DIRECTORY *pExportDir = (const IMAGE_EXPORT_DIRECTORY *)GetDirectoryData(pExportDirectoryEntry);
+
+ uint32_t namePointerCount = VAL32(pExportDir->NumberOfNames);
+ uint32_t addressTableRVA = VAL32(pExportDir->AddressOfFunctions);
+ uint32_t namePointersRVA = VAL32(pExportDir->AddressOfNames);
+
+ for (uint32_t nameIndex = 0; nameIndex < namePointerCount; nameIndex++)
+ {
+ uint32_t namePointerRVA = VAL32(*(const uint32_t *)&imageBase[namePointersRVA + sizeof(uint32_t) * nameIndex]);
+ if (namePointerRVA != 0)
+ {
+ const char *namePointer = (const char *)&imageBase[namePointerRVA];
+ if (!strcmp(namePointer, exportName))
+ {
+ uint32_t exportRVA = VAL32(*(const uint32_t *)&imageBase[addressTableRVA + sizeof(uint32_t) * nameIndex]);
+ return &imageBase[exportRVA];
+ }
+ }
+ }
+
+ return NULL;
+}
+#endif
+
//
// code:PEDecoder::CheckILMethod and code:PEDecoder::ComputeILMethodSize really belong to
// file:..\inc\corhlpr.cpp. Unfortunately, corhlpr.cpp is public header file that cannot be
READYTORUN_HEADER * pHeader = GetReadyToRunHeader();
PTR_READYTORUN_SECTION pSections = dac_cast<PTR_READYTORUN_SECTION>(dac_cast<TADDR>(pHeader) + sizeof(READYTORUN_HEADER));
- for (DWORD i = 0; i < pHeader->NumberOfSections; i++)
+ for (DWORD i = 0; i < pHeader->CoreHeader.NumberOfSections; i++)
{
// Verify that section types are sorted
_ASSERTE(i == 0 || (pSections[i - 1].Type < pSections[i].Type));
methodimpl.cpp
methoditer.cpp
methodtable.cpp
+ nativeimage.cpp
object.cpp
pefile.cpp
peimage.cpp
// See the LICENSE file in the project root for more information.
#include "common.h"
+#include "nativeimage.h"
AssemblyLoadContext::AssemblyLoadContext()
{
*pBinderId = reinterpret_cast<UINT_PTR>(this);
return S_OK;
}
+
+#ifndef DACCESS_COMPILE
+NativeImage *AssemblyLoadContext::LoadNativeImage(Module *componentModule, LPCUTF8 nativeImageName)
+{
+ STANDARD_VM_CONTRACT;
+
+ BaseDomain::LoadLockHolder lock(AppDomain::GetCurrentDomain());
+ AssemblyLoadContext *loadContext = componentModule->GetFile()->GetAssemblyLoadContext();
+ PTR_LoaderAllocator moduleLoaderAllocator = componentModule->GetLoaderAllocator();
+
+ int nativeImageCount = m_nativeImages.GetCount();
+#ifndef FEATURE_CASE_SENSITIVE_FILESYSTEM
+ SString nativeImageNameString;
+ nativeImageNameString.SetUTF8(nativeImageName);
+#endif
+ for (int nativeImageIndex = 0; nativeImageIndex < nativeImageCount; nativeImageIndex++)
+ {
+ NativeImage *nativeImage = m_nativeImages[nativeImageIndex];
+ LPCUTF8 existingImageFileName = nativeImage->GetFileName();
+#ifdef FEATURE_CASE_SENSITIVE_FILESYSTEM
+ bool match = (strcmp(nativeImageName, existingImageFileName) == 0);
+#else
+ bool match = SString(SString::Utf8Literal, existingImageFileName).EqualsCaseInsensitive(nativeImageNameString);
+#endif
+ if (match)
+ {
+ return nativeImage;
+ }
+ }
+
+ SString path = componentModule->GetPath();
+ SString::Iterator lastPathSeparatorIter = path.End();
+ size_t pathDirLength = 0;
+ if (PEAssembly::FindLastPathSeparator(path, lastPathSeparatorIter))
+ {
+ pathDirLength = (lastPathSeparatorIter - path.Begin()) + 1;
+ }
+
+ SString compositeImageFileName(SString::Utf8, nativeImageName);
+ SString fullPath;
+ fullPath.Set(path, path.Begin(), (COUNT_T)pathDirLength);
+ fullPath += compositeImageFileName;
+
+ AllocMemTracker amTracker;
+ NativeImage *nativeImage = NativeImage::Open(fullPath, nativeImageName, moduleLoaderAllocator, &amTracker);
+ if (nativeImage != NULL)
+ {
+ m_nativeImages.Append(nativeImage);
+ amTracker.SuppressRelease();
+ return nativeImage;
+ }
+
+ return NULL;
+}
+#endif
#ifndef _ASSEMBLYLOADCONTEXT_H
#define _ASSEMBLYLOADCONTEXT_H
+#include "crst.h"
+
+class NativeImage;
+class Module;
+
//
// Unmanaged counter-part of System.Runtime.Loader.AssemblyLoadContext
//
STDMETHOD(GetBinderID)(
/* [retval][out] */ UINT_PTR* pBinderId);
+
+ NativeImage *LoadNativeImage(Module *componentModule, LPCUTF8 nativeImageName);
+
+private:
+ SArray<NativeImage *> m_nativeImages;
};
#endif
#include "metadataexports.h"
#include "inlinetracking.h"
#include "threads.h"
+#include "nativeimage.h"
#ifdef FEATURE_PREJIT
#include "exceptionhandling.h"
}
#endif // FEATURE_PREJIT
+uint32_t Module::GetNativeMetadataAssemblyCount()
+{
+ NativeImage *compositeImage = GetCompositeNativeImage();
+ if (compositeImage != NULL)
+ {
+ return compositeImage->GetComponentAssemblyCount();
+ }
+ else
+ {
+ return GetNativeAssemblyImport()->GetCountWithTokenKind(mdtAssemblyRef);
+ }
+}
+
void Module::SetNativeMetadataAssemblyRefInCache(DWORD rid, PTR_Assembly pAssembly)
{
CONTRACTL
if (m_NativeMetadataAssemblyRefMap == NULL)
{
- IMDInternalImport* pImport = GetNativeAssemblyImport();
- DWORD dwMaxRid = pImport->GetCountWithTokenKind(mdtAssemblyRef);
+ uint32_t dwMaxRid = GetNativeMetadataAssemblyCount();
_ASSERTE(dwMaxRid > 0);
S_SIZE_T dwAllocSize = S_SIZE_T(sizeof(PTR_Assembly)) * S_SIZE_T(dwMaxRid);
}
_ASSERTE(m_NativeMetadataAssemblyRefMap != NULL);
- _ASSERTE(rid <= GetNativeAssemblyImport()->GetCountWithTokenKind(mdtAssemblyRef));
+ _ASSERTE(rid <= GetNativeMetadataAssemblyCount());
m_NativeMetadataAssemblyRefMap[rid - 1] = pAssembly;
}
// TODO: Verify that eager fixup dependency graphs can contain no cycles
OVERRIDE_TYPE_LOAD_LEVEL_LIMIT(CLASS_LOADED);
+ NativeImage *compositeNativeImage = GetCompositeNativeImage();
+ if (compositeNativeImage != NULL)
+ {
+ // For composite images, multiple modules may request initializing eager fixups
+ // from multiple threads so we need to lock their resolution.
+ if (compositeNativeImage->EagerFixupsHaveRun())
+ {
+ return;
+ }
+ CrstHolder compositeEagerFixups(compositeNativeImage->EagerFixupsLock());
+ if (compositeNativeImage->EagerFixupsHaveRun())
+ {
+ return;
+ }
+ RunEagerFixupsUnlocked();
+ compositeNativeImage->SetEagerFixupsHaveRun();
+ }
+ else
+ {
+ // Per-module eager fixups don't need locking
+ RunEagerFixupsUnlocked();
+ }
+}
+
+void Module::RunEagerFixupsUnlocked()
+{
+ COUNT_T nSections;
+ PTR_CORCOMPILE_IMPORT_SECTION pSections = GetImportSections(&nSections);
PEImageLayout *pNativeImage = GetNativeOrReadyToRunImage();
for (COUNT_T iSection = 0; iSection < nSections; iSection++)
PTR_CORCOMPILE_IMPORT_SECTION pImportSections, COUNT_T nImportSections,
PEDecoder * pNativeImage);
void RunEagerFixups();
+ void RunEagerFixupsUnlocked();
Module *GetModuleFromIndex(DWORD ix);
Module *GetModuleFromIndexIfLoaded(DWORD ix);
#endif // FEATURE_PREJIT
- BOOL IsReadyToRun()
+ BOOL IsReadyToRun() const
{
LIMITED_METHOD_DAC_CONTRACT;
#endif
}
+ NativeImage *GetCompositeNativeImage() const
+ {
+ LIMITED_METHOD_DAC_CONTRACT;
+ return (m_pReadyToRunInfo != NULL ? m_pReadyToRunInfo->GetNativeImage() : NULL);
+ }
+
#ifdef FEATURE_READYTORUN
- PTR_ReadyToRunInfo GetReadyToRunInfo()
+ PTR_ReadyToRunInfo GetReadyToRunInfo() const
{
LIMITED_METHOD_DAC_CONTRACT;
return m_pReadyToRunInfo;
if (NativeMetadataAssemblyRefMap == NULL)
return NULL;
- _ASSERTE(rid <= GetNativeAssemblyImport()->GetCountWithTokenKind(mdtAssemblyRef));
+ _ASSERTE(rid <= GetNativeMetadataAssemblyCount());
return NativeMetadataAssemblyRefMap[rid - 1];
}
void SetNativeMetadataAssemblyRefInCache(DWORD rid, PTR_Assembly pAssembly);
+
+ uint32_t GetNativeMetadataAssemblyCount();
#endif // !defined(DACCESS_COMPILE)
// For protecting dictionary layout slot expansions
../methodtablebuilder.cpp
../mlinfo.cpp
../mscorlib.cpp
+ ../nativeimage.cpp
../olevariant.cpp
../pefile.cpp
../peimage.cpp
}
}
-
#endif // #ifdef DACCESS_COMPILE
-
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+// --------------------------------------------------------------------------------
+// NativeImage.cpp
+//
+
+// --------------------------------------------------------------------------------
+
+#include "common.h"
+#include "nativeimage.h"
+
+// --------------------------------------------------------------------------------
+// Headers
+// --------------------------------------------------------------------------------
+
+#include <shlwapi.h>
+
+BOOL AssemblyNameIndexHashTraits::Equals(LPCUTF8 a, LPCUTF8 b)
+{
+ WRAPPER_NO_CONTRACT;
+
+ return SString(SString::Utf8Literal, a).Compare(SString(SString::Utf8Literal, b)) == 0;
+}
+
+AssemblyNameIndexHashTraits::count_t AssemblyNameIndexHashTraits::Hash(LPCUTF8 s)
+{
+ WRAPPER_NO_CONTRACT;
+
+ return SString(SString::Utf8Literal, s).HashCaseInsensitive();
+}
+
+NativeImage::NativeImage(PEImageLayout *pImageLayout, LPCUTF8 imageFileName)
+ : m_eagerFixupsLock(CrstNativeImageEagerFixups)
+{
+ CONTRACTL
+ {
+ THROWS;
+ CONSTRUCTOR_CHECK;
+ STANDARD_VM_CHECK;
+ INJECT_FAULT(COMPlusThrowOM(););
+ }
+ CONTRACTL_END;
+
+ m_pImageLayout = pImageLayout;
+ m_fileName = imageFileName;
+ m_eagerFixupsHaveRun = false;
+}
+
+void NativeImage::Initialize(READYTORUN_HEADER *pHeader, LoaderAllocator *pLoaderAllocator, AllocMemTracker *pamTracker)
+{
+ LoaderHeap *pHeap = pLoaderAllocator->GetHighFrequencyHeap();
+
+ m_pReadyToRunInfo = new ReadyToRunInfo(/*pModule*/ NULL, m_pImageLayout, pHeader, /*compositeImage*/ NULL, pamTracker);
+ m_pComponentAssemblies = m_pReadyToRunInfo->FindSection(ReadyToRunSectionType::ComponentAssemblies);
+ m_componentAssemblyCount = m_pComponentAssemblies->Size / sizeof(READYTORUN_COMPONENT_ASSEMBLIES_ENTRY);
+
+ // Check if the current module's image has native manifest metadata, otherwise the current->GetNativeAssemblyImport() asserts.
+ m_pManifestMetadata = LoadManifestMetadata();
+
+ HENUMInternal assemblyEnum;
+ HRESULT hr = m_pManifestMetadata->EnumAllInit(mdtAssemblyRef, &assemblyEnum);
+ mdAssemblyRef assemblyRef;
+ int assemblyIndex = 0;
+ while (m_pManifestMetadata->EnumNext(&assemblyEnum, &assemblyRef))
+ {
+ LPCSTR assemblyName;
+ hr = m_pManifestMetadata->GetAssemblyRefProps(assemblyRef, NULL, NULL, &assemblyName, NULL, NULL, NULL, NULL);
+ m_assemblySimpleNameToIndexMap.Add(AssemblyNameIndex(assemblyName, assemblyIndex));
+ assemblyIndex++;
+ }
+}
+
+NativeImage::~NativeImage()
+{
+ STANDARD_VM_CONTRACT;
+
+ delete m_pReadyToRunInfo;
+ delete m_pImageLayout;
+
+ if (m_pManifestMetadata != NULL)
+ {
+ m_pManifestMetadata->Release();
+ }
+}
+
+#ifndef DACCESS_COMPILE
+NativeImage *NativeImage::Open(
+ LPCWSTR fullPath,
+ LPCUTF8 nativeImageFileName,
+ LoaderAllocator *pLoaderAllocator,
+ AllocMemTracker *pamTracker)
+{
+ STANDARD_VM_CONTRACT;
+
+ NewHolder<PEImageLayout> peLoadedImage = PEImageLayout::LoadNative(fullPath);
+
+ READYTORUN_HEADER *pHeader = (READYTORUN_HEADER *)peLoadedImage->GetExport("RTR_HEADER");
+ if (pHeader == NULL)
+ {
+ COMPlusThrowHR(COR_E_BADIMAGEFORMAT);
+ }
+ if (pHeader->Signature != READYTORUN_SIGNATURE)
+ {
+ COMPlusThrowHR(COR_E_BADIMAGEFORMAT);
+ }
+ if (pHeader->MajorVersion < MINIMUM_READYTORUN_MAJOR_VERSION || pHeader->MajorVersion > READYTORUN_MAJOR_VERSION)
+ {
+ COMPlusThrowHR(COR_E_BADIMAGEFORMAT);
+ }
+ NewHolder<NativeImage> image = new NativeImage(peLoadedImage.Extract(), nativeImageFileName);
+ image->Initialize(pHeader, pLoaderAllocator, pamTracker);
+ return image.Extract();
+}
+#endif
+
+#ifndef DACCESS_COMPILE
+Assembly *NativeImage::LoadComponentAssembly(uint32_t rowid)
+{
+ STANDARD_VM_CONTRACT;
+
+ AssemblySpec spec;
+ spec.InitializeSpec(TokenFromRid(rowid, mdtAssemblyRef), m_pManifestMetadata, NULL);
+ return spec.LoadAssembly(FILE_LOADED);
+}
+#endif
+
+#ifndef DACCESS_COMPILE
+PTR_READYTORUN_CORE_HEADER NativeImage::GetComponentAssemblyHeader(LPCUTF8 simpleName)
+{
+ STANDARD_VM_CONTRACT;
+
+ const AssemblyNameIndex *assemblyNameIndex = m_assemblySimpleNameToIndexMap.LookupPtr(simpleName);
+ if (assemblyNameIndex != NULL)
+ {
+ const BYTE *pImageBase = (const BYTE *)m_pImageLayout->GetBase();
+ const READYTORUN_COMPONENT_ASSEMBLIES_ENTRY *componentAssembly =
+ (const READYTORUN_COMPONENT_ASSEMBLIES_ENTRY *)&pImageBase[m_pComponentAssemblies->VirtualAddress] + assemblyNameIndex->Index;
+ return (PTR_READYTORUN_CORE_HEADER)&pImageBase[componentAssembly->ReadyToRunCoreHeader.VirtualAddress];
+ }
+ return NULL;
+}
+#endif
+
+#ifndef DACCESS_COMPILE
+IMDInternalImport *NativeImage::LoadManifestMetadata()
+{
+ STANDARD_VM_CONTRACT;
+
+ IMAGE_DATA_DIRECTORY *pMeta = m_pReadyToRunInfo->FindSection(ReadyToRunSectionType::ManifestMetadata);
+
+ if (pMeta == NULL)
+ {
+ return NULL;
+ }
+
+ IMDInternalImport *pNewImport = NULL;
+ IfFailThrow(GetMetaDataInternalInterface((BYTE *)m_pImageLayout->GetBase() + VAL32(pMeta->VirtualAddress),
+ VAL32(pMeta->Size),
+ ofRead,
+ IID_IMDInternalImport,
+ (void **) &pNewImport));
+
+ return pNewImport;
+}
+#endif
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+#ifndef _NATIVEIMAGE_H
+#define _NATIVEIMAGE_H
+
+#include "readytoruninfo.h"
+
+// This structure is used in NativeImage to map simple names of component assemblies
+// to their indices within the component assembly header table.
+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; }
+};
+
+class AssemblyNameIndexHashTraits : public NoRemoveSHashTraits< DefaultSHashTraits<AssemblyNameIndex> >
+{
+public:
+ // Similar to BaseAssemblySpec::CompareStrings, we're using temporary SStrings that throw
+ // for case-insensitive UTF8 assembly name comparisons.
+ static const bool s_NoThrow = false;
+
+ typedef LPCUTF8 key_t;
+
+ static AssemblyNameIndex Null() { return AssemblyNameIndex::GetNull(); }
+ static bool IsNull(const AssemblyNameIndex& e) { return e.IsNull(); }
+
+ static LPCUTF8 GetKey(const AssemblyNameIndex& assemblyNameIndex) { return assemblyNameIndex.Name; }
+ static BOOL Equals(LPCUTF8 a, LPCUTF8 b);
+ static count_t Hash(LPCUTF8 a);
+};
+
+class AssemblyLoadContext;
+class ReadyToRunInfo;
+class PEFile;
+class PEImage;
+
+// This class represents a ReadyToRun image with native OS-specific envelope. As of today,
+// this file format is used as the compiled native code cache in composite R2R Crossgen2
+// build mode. Moving forward we plan to add support for OS-specific native executables
+// (ELF on Linux, MachO on OSX).
+//
+// The native image is identified by a well-known public export 'RTR_HEADER' pointing to the
+// master READYTORUN_HEADER structure for the entire file. For composite R2R executables
+// built by crossgenning a larger number of input MSIL assemblies the READYTORUN_HEADER
+// contains a section named ComponentAssemblies that points to READYTORUN_CORE_HEADER
+// structures representing the individual component assemblies and per-assembly sections.
+class NativeImage
+{
+private:
+ // Points to the OwnerCompositeExecutable section content within the component MSIL module
+ LPCUTF8 m_fileName;
+
+ ReadyToRunInfo *m_pReadyToRunInfo;
+ IMDInternalImport *m_pManifestMetadata;
+ PEImageLayout *m_pImageLayout;
+
+ IMAGE_DATA_DIRECTORY *m_pComponentAssemblies;
+ uint32_t m_componentAssemblyCount;
+ SHash<AssemblyNameIndexHashTraits> m_assemblySimpleNameToIndexMap;
+
+ Crst m_eagerFixupsLock;
+ bool m_eagerFixupsHaveRun;
+
+private:
+ NativeImage(PEImageLayout *peImageLayout, LPCUTF8 imageFileName);
+
+protected:
+ void Initialize(READYTORUN_HEADER *header, LoaderAllocator *loaderAllocator, AllocMemTracker *pamTracker);
+
+public:
+ ~NativeImage();
+
+ static NativeImage *Open(
+ LPCWSTR fullPath,
+ LPCUTF8 nativeImageFileName,
+ LoaderAllocator *pLoaderAllocator,
+ AllocMemTracker *pamTracker);
+
+ Crst *EagerFixupsLock() { return &m_eagerFixupsLock; }
+ bool EagerFixupsHaveRun() const { return m_eagerFixupsHaveRun; }
+ void SetEagerFixupsHaveRun() { m_eagerFixupsHaveRun = true; }
+ LPCUTF8 GetFileName() const { return m_fileName; }
+
+ uint32_t GetComponentAssemblyCount() const { return m_componentAssemblyCount; }
+ ReadyToRunInfo *GetReadyToRunInfo() const { return m_pReadyToRunInfo; }
+ IMDInternalImport *GetManifestMetadata() const { return m_pManifestMetadata; }
+
+ Assembly *LoadComponentAssembly(uint32_t rowid);
+
+ PTR_READYTORUN_CORE_HEADER GetComponentAssemblyHeader(LPCUTF8 assemblySimpleName);
+
+private:
+ IMDInternalImport *LoadManifestMetadata();
+};
+
+#endif
BOOL HasCorHeader();
BOOL HasReadyToRunHeader();
BOOL IsReferenceAssembly();
+ BOOL IsComponentAssembly();
#ifdef FEATURE_PREJIT
BOOL IsNativeILILOnly();
BOOL IsNativeILDll();
}
}
+inline BOOL PEImage::IsComponentAssembly()
+{
+ WRAPPER_NO_CONTRACT;
+ if (HasLoadedLayout())
+ return GetLoadedLayout()->IsComponentAssembly();
+ else
+ {
+ PEImageLayoutHolder pLayout(GetLayout(PEImageLayout::LAYOUT_ANY,LAYOUT_CREATEIFNEEDED));
+ return pLayout->IsComponentAssembly();
+ }
+}
+
inline BOOL PEImage::HasReadyToRunHeader()
{
WRAPPER_NO_CONTRACT;
return new FlatImageLayout(pOwner);
}
+PEImageLayout *PEImageLayout::LoadNative(LPCWSTR fullPath)
+{
+ STANDARD_VM_CONTRACT;
+ return new NativeImageLayout(fullPath);
+}
+
PEImageLayout* PEImageLayout::Map(PEImage* pOwner)
{
CONTRACT(PEImageLayout*)
Init(m_FileView, size);
}
+NativeImageLayout::NativeImageLayout(LPCWSTR fullPath)
+{
+ PVOID loadedImage;
+#if TARGET_UNIX
+ {
+ ErrorModeHolder mode(SEM_NOOPENFILEERRORBOX|SEM_FAILCRITICALERRORS);
+ HANDLE fileHandle = WszCreateFile(
+ fullPath,
+ GENERIC_READ,
+ FILE_SHARE_READ | FILE_SHARE_DELETE,
+ NULL,
+ OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+
+ if (fileHandle == INVALID_HANDLE_VALUE)
+ {
+ ThrowLastError();
+ }
-#endif // !DACESS_COMPILE
+ loadedImage = PAL_LOADLoadPEFile(fileHandle);
+ }
+#else
+ loadedImage = CLRLoadLibraryEx(fullPath, NULL, GetLoadWithAlteredSearchPathFlag());
+#endif
+
+ if (loadedImage == NULL)
+ {
+ ThrowLastError();
+ }
+#if TARGET_UNIX
+ PEDecoder::Init(loadedImage, /* relocated */ false);
+ ApplyBaseRelocations();
+ SetRelocated();
+#else // TARGET_UNIX
+ PEDecoder::Init(loadedImage, /* relocated */ true);
+#endif // TARGET_UNIX
+}
+#endif // !DACESS_COMPILE
#ifdef DACCESS_COMPILE
void
static PEImageLayout* LoadFromFlat(PEImageLayout* pflatimage);
static PEImageLayout* Load(PEImage* pOwner, BOOL bNTSafeLoad, BOOL bThrowOnError = TRUE);
static PEImageLayout* LoadFlat(PEImage* pOwner);
+ static PEImageLayout* LoadNative(LPCWSTR fullPath);
static PEImageLayout* Map(PEImage* pOwner);
#endif
PEImageLayout();
};
+#ifndef DACCESS_COMPILE
+class NativeImageLayout : public PEImageLayout
+{
+ VPTR_VTABLE_CLASS(NativeImageLayout, PEImageLayout)
+public:
+ NativeImageLayout(LPCWSTR fullPath);
+};
+#endif
#endif // PEIMAGELAYOUT_H_
#include "typehashingalgorithms.h"
#include "method.hpp"
#include "wellknownattributes.h"
+#include "nativeimage.h"
using namespace NativeFormat;
-IMAGE_DATA_DIRECTORY * ReadyToRunInfo::FindSection(ReadyToRunSectionType type)
+ReadyToRunCoreInfo::ReadyToRunCoreInfo()
+{
+}
+
+ReadyToRunCoreInfo::ReadyToRunCoreInfo(PEImageLayout* pLayout, READYTORUN_CORE_HEADER *pCoreHeader)
+ : m_pLayout(pLayout), m_pCoreHeader(pCoreHeader)
+{
+}
+
+IMAGE_DATA_DIRECTORY * ReadyToRunCoreInfo::FindSection(ReadyToRunSectionType type) const
{
CONTRACTL
{
}
CONTRACTL_END;
- PTR_READYTORUN_SECTION pSections = dac_cast<PTR_READYTORUN_SECTION>(dac_cast<TADDR>(m_pHeader) + sizeof(READYTORUN_HEADER));
- for (DWORD i = 0; i < m_pHeader->NumberOfSections; i++)
+ PTR_READYTORUN_SECTION pSections = dac_cast<PTR_READYTORUN_SECTION>(dac_cast<TADDR>(m_pCoreHeader) + sizeof(READYTORUN_CORE_HEADER));
+ for (DWORD i = 0; i < m_pCoreHeader->NumberOfSections; i++)
{
// Verify that section types are sorted
_ASSERTE(i == 0 || (pSections[i-1].Type < pSections[i].Type));
return NULL;
#endif
- TADDR val = (TADDR)m_entryPointToMethodDescMap.LookupValue(PCODEToPINSTR(entryPoint), (LPVOID)PCODEToPINSTR(entryPoint));
- if (val == (TADDR)INVALIDENTRY)
- return NULL;
- return dac_cast<PTR_MethodDesc>(val);
+ return m_pCompositeInfo->TryGetMethodDescForEntryPoint(entryPoint);
}
BOOL ReadyToRunInfo::HasHashtableOfTypes()
}
CONTRACTL_END;
- IMAGE_DATA_DIRECTORY * pDebugInfoDir = FindSection(ReadyToRunSectionType::DebugInfo);
+ IMAGE_DATA_DIRECTORY * pDebugInfoDir = m_pComposite->FindSection(ReadyToRunSectionType::DebugInfo);
if (pDebugInfoDir == NULL)
return NULL;
if (lookBack != 0)
debugInfoOffset = offset - lookBack;
- return dac_cast<PTR_BYTE>(m_pLayout->GetBase()) + debugInfoOffset;
+ return dac_cast<PTR_BYTE>(m_pComposite->GetLayout()->GetBase()) + debugInfoOffset;
+}
+
+MethodDesc *ReadyToRunInfo::TryGetMethodDescForEntryPoint(TADDR entryPointRVA)
+{
+ CONTRACTL
+ {
+ GC_NOTRIGGER;
+ NOTHROW;
+ SUPPORTS_DAC;
+ PRECONDITION(!m_isComponentAssembly);
+ }
+ CONTRACTL_END;
+
+ TADDR val = (TADDR)m_entryPointToMethodDescMap.LookupValue(PCODEToPINSTR(entryPointRVA), (LPVOID)PCODEToPINSTR(entryPointRVA));
+ if (val == (TADDR)INVALIDENTRY)
+ return NULL;
+ return dac_cast<PTR_MethodDesc>(val);
}
#ifndef DACCESS_COMPILE
+void ReadyToRunInfo::SetMethodDescForEntryPoint(TADDR entryPointRVA, MethodDesc *methodDesc)
+{
+ CONTRACTL
+ {
+ PRECONDITION(!m_isComponentAssembly);
+ }
+ CONTRACTL_END;
+
+ CrstHolder ch(&m_Crst);
+
+ if (m_entryPointToMethodDescMap.LookupValue(PCODEToPINSTR(entryPointRVA), (LPVOID)PCODEToPINSTR(entryPointRVA)) == (LPVOID)INVALIDENTRY)
+ {
+ m_entryPointToMethodDescMap.InsertValue(PCODEToPINSTR(entryPointRVA), methodDesc);
+ }
+}
+
BOOL ReadyToRunInfo::IsReadyToRunEnabled()
{
WRAPPER_NO_CONTRACT;
READYTORUN_IMPORT_SECTION * pImportSections = NULL;
READYTORUN_IMPORT_SECTION * pImportSectionsEnd = NULL;
READYTORUN_SECTION * pSections = (READYTORUN_SECTION*)(pHeader + 1);
- for (DWORD i = 0; i < pHeader->NumberOfSections; i++)
+ for (DWORD i = 0; i < pHeader->CoreHeader.NumberOfSections; i++)
{
if (pSections[i].Type == ReadyToRunSectionType::ImportSections)
{
return false;
}
+/// <summary>
+/// Try to locate composite R2R image for a given component module.
+/// </summary>
+static NativeImage *AcquireCompositeImage(Module * pModule, PEImageLayout * pLayout, READYTORUN_HEADER *pHeader)
+{
+ READYTORUN_SECTION * pSections = (READYTORUN_SECTION*)(pHeader + 1);
+ LPCUTF8 ownerCompositeExecutableName = NULL;
+ for (DWORD i = 0; i < pHeader->CoreHeader.NumberOfSections; i++)
+ {
+ if (pSections[i].Type == ReadyToRunSectionType::OwnerCompositeExecutable)
+ {
+ ownerCompositeExecutableName = (LPCUTF8)pLayout->GetBase() + pSections[i].Section.VirtualAddress;
+ break;
+ }
+ }
+
+ if (ownerCompositeExecutableName != NULL)
+ {
+ AssemblyLoadContext *loadContext = pModule->GetFile()->GetAssemblyLoadContext();
+ if (loadContext == nullptr)
+ {
+ loadContext = (AssemblyLoadContext *)AppDomain::GetCurrentDomain()->CreateBinderContext();
+ }
+ return loadContext->LoadNativeImage(pModule, ownerCompositeExecutableName);
+ }
+
+ return NULL;
+}
+
PTR_ReadyToRunInfo ReadyToRunInfo::Initialize(Module * pModule, AllocMemTracker *pamTracker)
{
STANDARD_VM_CONTRACT;
return NULL;
}
- if (!AcquireImage(pModule, pLayout, pHeader))
+ NativeImage *nativeImage = NULL;
+ if (pHeader->CoreHeader.Flags & READYTORUN_FLAG_COMPONENT)
{
- DoLog("Ready to Run disabled - module already loaded in another AppDomain");
- return NULL;
+ nativeImage = AcquireCompositeImage(pModule, pLayout, pHeader);
+ if (nativeImage == NULL)
+ {
+ DoLog("Ready to Run disabled - composite image not found");
+ return NULL;
+ }
+ }
+ else
+ {
+ if (!AcquireImage(pModule, pLayout, pHeader))
+ {
+ DoLog("Ready to Run disabled - module already loaded in another AppDomain");
+ return NULL;
+ }
}
LoaderHeap *pHeap = pModule->GetLoaderAllocator()->GetHighFrequencyHeap();
DoLog("Ready to Run initialized successfully");
- return new (pMemory) ReadyToRunInfo(pModule, pLayout, pHeader, pamTracker);
+ return new (pMemory) ReadyToRunInfo(pModule, pLayout, pHeader, nativeImage, pamTracker);
}
-ReadyToRunInfo::ReadyToRunInfo(Module * pModule, PEImageLayout * pLayout, READYTORUN_HEADER * pHeader, AllocMemTracker *pamTracker)
- : m_pModule(pModule), m_pLayout(pLayout), m_pHeader(pHeader), m_Crst(CrstReadyToRunEntryPointToMethodDescMap),
+ReadyToRunInfo::ReadyToRunInfo(Module * pModule, PEImageLayout * pLayout, READYTORUN_HEADER * pHeader, NativeImage *pNativeImage, AllocMemTracker *pamTracker)
+ : m_pModule(pModule),
+ m_pHeader(pHeader),
+ m_pNativeImage(pNativeImage),
+ m_Crst(CrstReadyToRunEntryPointToMethodDescMap),
m_pPersistentInlineTrackingMap(NULL)
{
STANDARD_VM_CONTRACT;
- IMAGE_DATA_DIRECTORY * pRuntimeFunctionsDir = FindSection(ReadyToRunSectionType::RuntimeFunctions);
+ if (pNativeImage != 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();
+ if (pNativeImage->GetComponentAssemblyCount() == 1)
+ {
+ // When there's just 1 component assembly in the composite image, we're skipping the
+ // assembly headers and store all sections directly in the main R2R header.
+ m_component = *m_pComposite;
+ }
+ else
+ {
+ m_component = ReadyToRunCoreInfo(m_pComposite->GetLayout(), pNativeImage->GetComponentAssemblyHeader(pModule->GetSimpleName()));
+ }
+ m_isComponentAssembly = true;
+ }
+ else
+ {
+ m_pCompositeInfo = this;
+ m_component = ReadyToRunCoreInfo(pLayout, &pHeader->CoreHeader);
+ m_pComposite = &m_component;
+ m_isComponentAssembly = false;
+ }
+
+ IMAGE_DATA_DIRECTORY * pRuntimeFunctionsDir = m_pComposite->FindSection(ReadyToRunSectionType::RuntimeFunctions);
if (pRuntimeFunctionsDir != NULL)
{
- m_pRuntimeFunctions = (T_RUNTIME_FUNCTION *)pLayout->GetDirectoryData(pRuntimeFunctionsDir);
+ m_pRuntimeFunctions = (T_RUNTIME_FUNCTION *)m_pComposite->GetLayout()->GetDirectoryData(pRuntimeFunctionsDir);
m_nRuntimeFunctions = pRuntimeFunctionsDir->Size / sizeof(T_RUNTIME_FUNCTION);
}
else
m_nRuntimeFunctions = 0;
}
- IMAGE_DATA_DIRECTORY * pImportSectionsDir = FindSection(ReadyToRunSectionType::ImportSections);
+ IMAGE_DATA_DIRECTORY * pImportSectionsDir = m_pComposite->FindSection(ReadyToRunSectionType::ImportSections);
if (pImportSectionsDir != NULL)
{
- m_pImportSections = (CORCOMPILE_IMPORT_SECTION*)pLayout->GetDirectoryData(pImportSectionsDir);
+ m_pImportSections = (CORCOMPILE_IMPORT_SECTION*)m_pComposite->GetLayout()->GetDirectoryData(pImportSectionsDir);
m_nImportSections = pImportSectionsDir->Size / sizeof(CORCOMPILE_IMPORT_SECTION);
}
else
m_nImportSections = 0;
}
- m_nativeReader = NativeReader((byte *)pLayout->GetBase(), pLayout->GetVirtualSize());
+ m_nativeReader = NativeReader((BYTE *)m_pComposite->GetLayout()->GetBase(), m_pComposite->GetLayout()->GetVirtualSize());
- IMAGE_DATA_DIRECTORY * pEntryPointsDir = FindSection(ReadyToRunSectionType::MethodDefEntryPoints);
+ IMAGE_DATA_DIRECTORY * pEntryPointsDir = m_component.FindSection(ReadyToRunSectionType::MethodDefEntryPoints);
if (pEntryPointsDir != NULL)
{
m_methodDefEntryPoints = NativeArray(&m_nativeReader, pEntryPointsDir->VirtualAddress);
}
- IMAGE_DATA_DIRECTORY * pinstMethodsDir = FindSection(ReadyToRunSectionType::InstanceMethodEntryPoints);
+ IMAGE_DATA_DIRECTORY * pinstMethodsDir = m_pComposite->FindSection(ReadyToRunSectionType::InstanceMethodEntryPoints);
if (pinstMethodsDir != NULL)
{
NativeParser parser = NativeParser(&m_nativeReader, pinstMethodsDir->VirtualAddress);
m_instMethodEntryPoints = NativeHashtable(parser);
}
- IMAGE_DATA_DIRECTORY * pAvailableTypesDir = FindSection(ReadyToRunSectionType::AvailableTypes);
+ IMAGE_DATA_DIRECTORY * pAvailableTypesDir = m_component.FindSection(ReadyToRunSectionType::AvailableTypes);
if (pAvailableTypesDir != NULL)
{
NativeParser parser = NativeParser(&m_nativeReader, pAvailableTypesDir->VirtualAddress);
m_availableTypesHashtable = NativeHashtable(parser);
}
+ if (!m_isComponentAssembly)
{
+ // For component assemblies we don't initialize the reverse lookup map mapping entry points to MethodDescs;
+ // we need to use the global map in the composite image ReadyToRunInfo instance to be able to reverse translate
+ // all methods within the composite image.
LockOwner lock = {&m_Crst, IsOwnerOfCrst};
m_entryPointToMethodDescMap.Init(TRUE, &lock);
}
// For format version 4.1 and later, there is an optional inlining table
if (IsImageVersionAtLeast(4, 1))
{
- IMAGE_DATA_DIRECTORY* pInlineTrackingInfoDir = FindSection(ReadyToRunSectionType::InliningInfo2);
+ IMAGE_DATA_DIRECTORY* pInlineTrackingInfoDir = m_pComposite->FindSection(ReadyToRunSectionType::InliningInfo2);
if (pInlineTrackingInfoDir != NULL)
{
- const BYTE* pInlineTrackingMapData = (const BYTE*)GetImage()->GetDirectoryData(pInlineTrackingInfoDir);
+ const BYTE* pInlineTrackingMapData = (const BYTE*)m_pComposite->GetImage()->GetDirectoryData(pInlineTrackingInfoDir);
PersistentInlineTrackingMapR2R2::TryLoad(pModule, pInlineTrackingMapData, pInlineTrackingInfoDir->Size,
pamTracker, (PersistentInlineTrackingMapR2R2**)&m_pPersistentInlineTrackingMap);
}
// For format version 2.1 and later, there is an optional inlining table
if (m_pPersistentInlineTrackingMap == nullptr && IsImageVersionAtLeast(2, 1))
{
- IMAGE_DATA_DIRECTORY * pInlineTrackingInfoDir = FindSection(ReadyToRunSectionType::InliningInfo);
+ IMAGE_DATA_DIRECTORY * pInlineTrackingInfoDir = m_pComposite->FindSection(ReadyToRunSectionType::InliningInfo);
if (pInlineTrackingInfoDir != NULL)
{
- const BYTE* pInlineTrackingMapData = (const BYTE*)GetImage()->GetDirectoryData(pInlineTrackingInfoDir);
+ const BYTE* pInlineTrackingMapData = (const BYTE*)m_pComposite->GetImage()->GetDirectoryData(pInlineTrackingInfoDir);
PersistentInlineTrackingMapR2R::TryLoad(pModule, pInlineTrackingMapData, pInlineTrackingInfoDir->Size,
pamTracker, &m_pPersistentInlineTrackingMap);
}
// For format version 2.2 and later, there is an optional profile-data section
if (IsImageVersionAtLeast(2, 2))
{
- IMAGE_DATA_DIRECTORY * pProfileDataInfoDir = FindSection(ReadyToRunSectionType::ProfileDataInfo);
+ IMAGE_DATA_DIRECTORY * pProfileDataInfoDir = m_pComposite->FindSection(ReadyToRunSectionType::ProfileDataInfo);
if (pProfileDataInfoDir != NULL)
{
CORCOMPILE_METHOD_PROFILE_LIST * pMethodProfileList;
- pMethodProfileList = (CORCOMPILE_METHOD_PROFILE_LIST *)GetImage()->GetDirectoryData(pProfileDataInfoDir);
+ pMethodProfileList = (CORCOMPILE_METHOD_PROFILE_LIST *)m_pComposite->GetImage()->GetDirectoryData(pProfileDataInfoDir);
pModule->SetMethodProfileList(pMethodProfileList);
}
}
// For format version 3.1 and later, there is an optional attributes section
- IMAGE_DATA_DIRECTORY *attributesPresenceDataInfoDir = FindSection(ReadyToRunSectionType::AttributePresence);
+ IMAGE_DATA_DIRECTORY *attributesPresenceDataInfoDir = m_component.FindSection(ReadyToRunSectionType::AttributePresence);
if (attributesPresenceDataInfoDir != NULL)
{
NativeCuckooFilter newFilter(
- (byte *)pLayout->GetBase(),
- pLayout->GetVirtualSize(),
+ (BYTE *)m_pComposite->GetLayout()->GetBase(),
+ m_pComposite->GetLayout()->GetVirtualSize(),
attributesPresenceDataInfoDir->VirtualAddress,
attributesPresenceDataInfoDir->Size);
if (fFixups)
{
- if (!m_pModule->FixupDelayList(dac_cast<TADDR>(m_pLayout->GetBase()) + offset))
+ if (!m_pModule->FixupDelayList(dac_cast<TADDR>(GetImage()->GetBase()) + offset))
{
#ifndef CROSSGEN_COMPILE
pConfig->SetReadyToRunRejectedPrecompiledCode();
}
_ASSERTE(id < m_nRuntimeFunctions);
- pEntryPoint = dac_cast<TADDR>(m_pLayout->GetBase()) + m_pRuntimeFunctions[id].BeginAddress;
-
- {
- CrstHolder ch(&m_Crst);
-
- if (m_entryPointToMethodDescMap.LookupValue(PCODEToPINSTR(pEntryPoint), (LPVOID)PCODEToPINSTR(pEntryPoint)) == (LPVOID)INVALIDENTRY)
- m_entryPointToMethodDescMap.InsertValue(PCODEToPINSTR(pEntryPoint), pMD);
- }
+ pEntryPoint = dac_cast<TADDR>(GetImage()->GetBase()) + m_pRuntimeFunctions[id].BeginAddress;
+ m_pCompositeInfo->SetMethodDescForEntryPoint(pEntryPoint, pMD);
#ifndef CROSSGEN_COMPILE
#ifdef PROFILING_SUPPORTED
return pEntryPoint;
}
-
void ReadyToRunInfo::MethodIterator::ParseGenericMethodSignatureAndRid(uint *pOffset, RID *pRid)
{
_ASSERTE(!m_genericParser.IsNull());
}
_ASSERTE(id < m_pInfo->m_nRuntimeFunctions);
- PCODE pEntryPoint = dac_cast<TADDR>(m_pInfo->m_pLayout->GetBase()) + m_pInfo->m_pRuntimeFunctions[id].BeginAddress;
+ PCODE pEntryPoint = dac_cast<TADDR>(m_pInfo->GetImage()->GetBase()) + m_pInfo->m_pRuntimeFunctions[id].BeginAddress;
return m_pInfo->GetMethodDescForEntryPoint(pEntryPoint);
}
BOOL ReadyToRunInfo::IsImageVersionAtLeast(int majorVersion, int minorVersion)
{
- LIMITED_METHOD_CONTRACT;
- return (m_pHeader->MajorVersion == majorVersion && m_pHeader->MinorVersion >= minorVersion) ||
- (m_pHeader->MajorVersion > majorVersion);
+ LIMITED_METHOD_CONTRACT;
+ return (m_pHeader->MajorVersion == majorVersion && m_pHeader->MinorVersion >= minorVersion) ||
+ (m_pHeader->MajorVersion > majorVersion);
}
typedef DPTR(struct READYTORUN_SECTION) PTR_READYTORUN_SECTION;
+class NativeImage;
class PrepareCodeConfig;
+typedef DPTR(class ReadyToRunCoreInfo) PTR_ReadyToRunCoreInfo;
+class ReadyToRunCoreInfo
+{
+private:
+ PTR_PEImageLayout m_pLayout;
+ PTR_READYTORUN_CORE_HEADER m_pCoreHeader;
+
+public:
+ ReadyToRunCoreInfo();
+ ReadyToRunCoreInfo(PEImageLayout * pLayout, READYTORUN_CORE_HEADER * pCoreHeader);
+
+ PEImageLayout * GetLayout() const { return m_pLayout; }
+ IMAGE_DATA_DIRECTORY * FindSection(ReadyToRunSectionType type) const;
+
+ PTR_PEImageLayout GetImage() const
+ {
+ LIMITED_METHOD_CONTRACT;
+ return m_pLayout;
+ }
+};
+
typedef DPTR(class ReadyToRunInfo) PTR_ReadyToRunInfo;
class ReadyToRunInfo
{
friend class ReadyToRunJitManager;
PTR_Module m_pModule;
-
- PTR_PEImageLayout m_pLayout;
PTR_READYTORUN_HEADER m_pHeader;
+ bool m_isComponentAssembly;
+ NativeImage* m_pNativeImage;
+ ReadyToRunInfo* m_pCompositeInfo;
+
+ ReadyToRunCoreInfo m_component;
+ const ReadyToRunCoreInfo* m_pComposite;
PTR_RUNTIME_FUNCTION m_pRuntimeFunctions;
DWORD m_nRuntimeFunctions;
NativeFormat::NativeArray m_methodDefEntryPoints;
NativeFormat::NativeHashtable m_instMethodEntryPoints;
NativeFormat::NativeHashtable m_availableTypesHashtable;
+
NativeFormat::NativeHashtable m_pMetaDataHashtable;
NativeFormat::NativeCuckooFilter m_attributesPresence;
PTR_PersistentInlineTrackingMapR2R m_pPersistentInlineTrackingMap;
- ReadyToRunInfo(Module * pModule, PEImageLayout * pLayout, READYTORUN_HEADER * pHeader, AllocMemTracker *pamTracker);
-
public:
+ ReadyToRunInfo(Module * pModule, PEImageLayout * pLayout, READYTORUN_HEADER * pHeader, NativeImage * pNativeImage, AllocMemTracker *pamTracker);
+
static BOOL IsReadyToRunEnabled();
static PTR_ReadyToRunInfo Initialize(Module * pModule, AllocMemTracker *pamTracker);
+ bool IsComponentAssembly() const { return m_isComponentAssembly; }
+ NativeImage * GetNativeImage() const { return m_pNativeImage; }
+
+ PTR_PEImageLayout 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);
MethodDesc * GetMethodDescForEntryPoint(PCODE entryPoint);
BOOL SkipTypeValidation()
{
LIMITED_METHOD_CONTRACT;
- return m_pHeader->Flags & READYTORUN_FLAG_SKIP_TYPE_VALIDATION;
+ return m_pHeader->CoreHeader.Flags & READYTORUN_FLAG_SKIP_TYPE_VALIDATION;
}
BOOL IsPartial()
{
LIMITED_METHOD_CONTRACT;
- return m_pHeader->Flags & READYTORUN_FLAG_PARTIAL;
+ return m_pHeader->CoreHeader.Flags & READYTORUN_FLAG_PARTIAL;
}
BOOL HasNonShareablePInvokeStubs()
{
LIMITED_METHOD_CONTRACT;
- return m_pHeader->Flags & READYTORUN_FLAG_NONSHARED_PINVOKE_STUBS;
+ return m_pHeader->CoreHeader.Flags & READYTORUN_FLAG_NONSHARED_PINVOKE_STUBS;
}
- PTR_PEImageLayout GetImage()
- {
- LIMITED_METHOD_CONTRACT;
- return m_pLayout;
- }
-
- IMAGE_DATA_DIRECTORY * FindSection(ReadyToRunSectionType type);
-
PTR_CORCOMPILE_IMPORT_SECTION GetImportSections(COUNT_T * pCount)
{
LIMITED_METHOD_CONTRACT;
BOOL GetTypeNameFromToken(IMDInternalImport * pImport, mdToken mdType, LPCUTF8 * ppszName, LPCUTF8 * ppszNameSpace);
BOOL GetEnclosingToken(IMDInternalImport * pImport, mdToken mdType, mdToken * pEnclosingToken);
BOOL CompareTypeNameOfTokens(mdToken mdToken1, IMDInternalImport * pImport1, mdToken mdToken2, IMDInternalImport * pImport2);
- BOOL IsImageVersionAtLeast(int majorVersion, int minorVersion);
+ BOOL IsImageVersionAtLeast(int majorVersion, int minorVersion);
+
+ MethodDesc *TryGetMethodDescForEntryPoint(TADDR entryPointRVA);
+ void SetMethodDescForEntryPoint(TADDR entryPointRVA, MethodDesc *methodDesc);
+
+ ReadyToRunCoreInfo *GetComponentInfo() { return &m_component; }
};
class DynamicHelpers
#include "typedesc.h"
#include "compile.h"
#include "sigbuilder.h"
+#include "nativeimage.h"
#ifndef DACCESS_COMPILE
CONTRACTL_END;
Assembly *pAssembly = NULL;
+ NativeImage *nativeImage = fromModule->GetCompositeNativeImage();
+ uint32_t assemblyRefMax = (nativeImage != NULL ? 0 : fromModule->GetAssemblyRefMax());
- if (index == 0)
+ if (index < assemblyRefMax)
{
- pAssembly = fromModule->GetAssembly();
- }
- else
- {
- if (index < fromModule->GetAssemblyRefMax())
+ if (index == 0)
{
- pAssembly = fromModule->LoadAssembly(RidToToken(index, mdtAssemblyRef))->GetAssembly();
+ pAssembly = fromModule->GetAssembly();
}
else
{
- index -= fromModule->GetAssemblyRefMax();
+ pAssembly = fromModule->LoadAssembly(RidToToken(index, mdtAssemblyRef))->GetAssembly();
+ }
+ }
+ else
+ {
+ index -= assemblyRefMax;
- pAssembly = fromModule->GetNativeMetadataAssemblyRefFromCache(index);
+ pAssembly = fromModule->GetNativeMetadataAssemblyRefFromCache(index);
- if(pAssembly == NULL)
+ if(pAssembly == NULL)
+ {
+ if (nativeImage != NULL)
+ {
+ pAssembly = nativeImage->LoadComponentAssembly(index);
+ }
+ else
{
AssemblySpec spec;
spec.InitializeSpec(TokenFromRid(index, mdtAssemblyRef),
- fromModule->GetNativeAssemblyImport(),
- NULL);
-
+ fromModule->GetNativeAssemblyImport(),
+ NULL);
pAssembly = spec.LoadAssembly(FILE_LOADED);
-
- fromModule->SetNativeMetadataAssemblyRefInCache(index, pAssembly);
}
+ fromModule->SetNativeMetadataAssemblyRefInCache(index, pAssembly);
}
}
Assembly *pAssembly = NULL;
mdAssemblyRef tkAssemblyRef;
- if (index == 0)
- pAssembly = fromModule->GetAssembly();
- else
+ NativeImage *nativeImage = fromModule->GetCompositeNativeImage();
+ uint32_t assemblyRefMax = (nativeImage != NULL ? 0 : fromModule->GetAssemblyRefMax());
+
+ if (index < assemblyRefMax)
{
- if (index < fromModule->GetAssemblyRefMax())
+ if (index == 0)
{
- tkAssemblyRef = RidToToken(index, mdtAssemblyRef);
- pAssembly = fromModule->GetAssemblyIfLoaded(tkAssemblyRef);
+ pAssembly = fromModule->GetAssembly();
}
else
{
- index -= fromModule->GetAssemblyRefMax();
- tkAssemblyRef = RidToToken(index, mdtAssemblyRef);
- IMDInternalImport * pMDImportOverride = fromModule->GetNativeAssemblyImport(FALSE);
- if (pMDImportOverride != NULL)
+ pAssembly = fromModule->GetAssemblyIfLoaded(RidToToken(index, mdtAssemblyRef));
+ }
+ }
+ else
+ {
+ index -= assemblyRefMax;
+ tkAssemblyRef = RidToToken(index, mdtAssemblyRef);
+ IMDInternalImport * pMDImportOverride = (nativeImage != NULL
+ ? nativeImage->GetManifestMetadata() : fromModule->GetNativeAssemblyImport(FALSE));
+ if (pMDImportOverride != NULL)
+ {
+ CHAR szFullName[MAX_CLASS_NAME + 1];
+ LPCSTR szWinRtNamespace = NULL;
+ LPCSTR szWinRtClassName = NULL;
+
+ BOOL fValidAssemblyRef = TRUE;
+ LPCSTR pAssemblyName;
+ DWORD dwFlags;
+ if (FAILED(pMDImportOverride->GetAssemblyRefProps(tkAssemblyRef,
+ NULL,
+ NULL,
+ &pAssemblyName,
+ NULL,
+ NULL,
+ NULL,
+ &dwFlags)))
+ { // Unexpected failure reading MetaData
+ fValidAssemblyRef = FALSE;
+ }
+
+ if (fValidAssemblyRef && IsAfContentType_WindowsRuntime(dwFlags))
{
- CHAR szFullName[MAX_CLASS_NAME + 1];
- LPCSTR szWinRtNamespace = NULL;
- LPCSTR szWinRtClassName = NULL;
-
- BOOL fValidAssemblyRef = TRUE;
- LPCSTR pAssemblyName;
- DWORD dwFlags;
- if (FAILED(pMDImportOverride->GetAssemblyRefProps(tkAssemblyRef,
- NULL,
- NULL,
- &pAssemblyName,
- NULL,
- NULL,
- NULL,
- &dwFlags)))
- { // Unexpected failure reading MetaData
- fValidAssemblyRef = FALSE;
- }
+ // Find the encoded type name
+ LPCSTR pTypeName = NULL;
+ if (pAssemblyName != NULL)
+ pTypeName = strchr(pAssemblyName, '!');
- if (fValidAssemblyRef && IsAfContentType_WindowsRuntime(dwFlags))
+ if (pTypeName != NULL)
{
- // Find the encoded type name
- LPCSTR pTypeName = NULL;
- if (pAssemblyName != NULL)
- pTypeName = strchr(pAssemblyName, '!');
+ pTypeName++;
+ // pTypeName now contains the full type name (namespace + name)
- if (pTypeName != NULL)
+ strcpy_s(szFullName, _countof(szFullName), pTypeName);
+ LPSTR pszName = strrchr(szFullName, '.');
+
+ // WinRT types must have a namespace
+ if (pszName != NULL)
{
- pTypeName++;
- // pTypeName now contains the full type name (namespace + name)
-
- strcpy_s(szFullName, _countof(szFullName), pTypeName);
- LPSTR pszName = strrchr(szFullName, '.');
-
- // WinRT types must have a namespace
- if (pszName != NULL)
- {
- // Replace . between namespace and name with null terminator.
- // This breaks the string into a namespace and name pair.
- *pszName = '\0';
- pszName++;
-
- szWinRtNamespace = szFullName;
- szWinRtClassName = pszName;
- }
- else
- { // Namespace '.' separator not found - invalid type name (namespace has to be always present)
- fValidAssemblyRef = FALSE;
- }
+ // Replace . between namespace and name with null terminator.
+ // This breaks the string into a namespace and name pair.
+ *pszName = '\0';
+ pszName++;
+
+ szWinRtNamespace = szFullName;
+ szWinRtClassName = pszName;
}
else
- { // Type name separator in assembly name '!' not found
+ { // Namespace '.' separator not found - invalid type name (namespace has to be always present)
fValidAssemblyRef = FALSE;
}
}
-
- if (fValidAssemblyRef)
- {
- pAssembly = fromModule->GetAssemblyIfLoaded(
- tkAssemblyRef,
- szWinRtNamespace,
- szWinRtClassName,
- pMDImportOverride);
+ else
+ { // Type name separator in assembly name '!' not found
+ fValidAssemblyRef = FALSE;
}
}
+
+ if (fValidAssemblyRef)
+ {
+ pAssembly = fromModule->GetAssemblyIfLoaded(
+ tkAssemblyRef,
+ szWinRtNamespace,
+ szWinRtClassName,
+ pMDImportOverride);
+ }
}
}
readyToRunHeader.MinorVersion = READYTORUN_MINOR_VERSION;
if (pImage->m_ModuleDecoder.IsPlatformNeutral())
- readyToRunHeader.Flags |= READYTORUN_FLAG_PLATFORM_NEUTRAL_SOURCE;
+ readyToRunHeader.CoreHeader.Flags |= READYTORUN_FLAG_PLATFORM_NEUTRAL_SOURCE;
// If all types loaded succesfully, set a flag to skip type loading sanity checks at runtime
if (pImage->GetCompileInfo()->AreAllClassesFullyLoaded(pImage->GetModuleHandle()))
- readyToRunHeader.Flags |= READYTORUN_FLAG_SKIP_TYPE_VALIDATION;
+ readyToRunHeader.CoreHeader.Flags |= READYTORUN_FLAG_SKIP_TYPE_VALIDATION;
if (pImage->GetZapperOptions()->m_fPartialNGen)
- readyToRunHeader.Flags |= READYTORUN_FLAG_PARTIAL;
+ readyToRunHeader.CoreHeader.Flags |= READYTORUN_FLAG_PARTIAL;
- readyToRunHeader.NumberOfSections = m_Sections.GetCount();
+ readyToRunHeader.CoreHeader.NumberOfSections = m_Sections.GetCount();
pZapWriter->Write(&readyToRunHeader, sizeof(readyToRunHeader));