1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
4 // --------------------------------------------------------------------------------
8 // --------------------------------------------------------------------------------
13 #include "strongname.h"
14 #include "strongnameholders.h"
16 #include "fusionbind.h"
19 #include "simplerwlock.hpp"
20 #include "eventtrace.h"
21 #include "peimagelayout.inl"
24 inline CHECK PEFile::Invariant()
37 // dynamic module case
38 CHECK(m_openedILimage == NULL);
40 CHECK(m_nativeImage == NULL);
42 CHECK(CheckPointer(m_pEmitter));
46 // If m_image is null, then we should have a native image. However, this is not valid initially
47 // during construction. We should find a way to assert this.
48 CHECK(CheckPointer((PEImage*) m_openedILimage, NULL_OK));
50 CHECK(CheckPointer((PEImage*) m_nativeImage, NULL_OK));
55 #endif // CHECK_INVARIANTS
57 // ------------------------------------------------------------
59 // ------------------------------------------------------------
61 inline ULONG PEFile::AddRef()
65 PRECONDITION(m_refCount < COUNT_T_MAX);
73 return FastInterlockIncrement(&m_refCount);
76 inline ULONG PEFile::Release()
87 LONG result = FastInterlockDecrement(&m_refCount);
88 _ASSERTE(result >= 0);
95 // ------------------------------------------------------------
97 // ------------------------------------------------------------
99 inline ULONG PEAssembly::HashIdentity()
103 PRECONDITION(CheckPointer(m_identity));
109 #ifdef FEATURE_VERSIONING
110 return BINDER_SPACE::GetAssemblyFromPrivAssemblyFast(m_pHostAssembly)->GetAssemblyName()->Hash(BINDER_SPACE::AssemblyName::INCLUDE_VERSION);
112 if (!m_identity->HasID())
117 return (ULONG) dac_cast<TADDR>(GetLoaded()->GetBase());
120 return m_identity->GetIDHash();
124 inline void PEFile::ValidateForExecution()
134 // We do not need to check NGen images; if it had the attribute, it would have failed to load
135 // at NGen time and so there would be no NGen image.
136 if (HasNativeImage() || IsIntrospectionOnly())
140 // Ensure reference assemblies are not loaded for execution
142 ReleaseHolder<IMDInternalImport> mdImport(this->GetMDImportWithRef());
143 if (mdImport->GetCustomAttributeByName(TokenFromRid(1, mdtAssembly),
144 g_ReferenceAssemblyAttribute,
147 ThrowHR(COR_E_LOADING_REFERENCE_ASSEMBLY, BFA_REFERENCE_ASSEMBLY);
151 // Ensure platform is valid for execution
153 if (!IsDynamic() && !IsResource())
155 if (IsMarkedAsNoPlatform())
157 if (IsMarkedAsContentTypeWindowsRuntime())
159 ThrowHR(COR_E_LOADING_WINMD_REFERENCE_ASSEMBLY);
163 ThrowHR(COR_E_BADIMAGEFORMAT);
170 inline BOOL PEFile::IsMarkedAsNoPlatform()
173 return (IsAfPA_NoPlatform(GetFlags()));
176 inline BOOL PEFile::IsMarkedAsContentTypeWindowsRuntime()
179 return (IsAfContentType_WindowsRuntime(GetFlags()));
183 inline void PEFile::GetMVID(GUID *pMvid)
194 IfFailThrow(GetPersistentMDImport()->GetScopeProps(NULL, pMvid));
197 inline BOOL PEFile::PassiveDomainOnly()
200 return HasOpenedILimage() && GetOpenedILimage()->PassiveDomainOnly();
203 // ------------------------------------------------------------
204 // Loader support routines
205 // ------------------------------------------------------------
207 inline void PEFile::SetSkipVerification()
209 LIMITED_METHOD_CONTRACT;
211 m_flags |= PEFILE_SKIP_VERIFICATION;
214 inline BOOL PEFile::HasSkipVerification()
216 LIMITED_METHOD_CONTRACT;
218 return (m_flags & (PEFILE_SKIP_VERIFICATION | PEFILE_SYSTEM)) != 0;
221 // ------------------------------------------------------------
222 // Descriptive strings
223 // ------------------------------------------------------------
225 inline const SString &PEFile::GetPath()
241 return SString::Empty();
244 return m_identity->GetPath();
248 #ifdef DACCESS_COMPILE
249 inline const SString &PEFile::GetModuleFileNameHint()
262 return SString::Empty();
265 return m_identity->GetModuleFileNameHintForDAC();
267 #endif // DACCESS_COMPILE
270 inline LPCWSTR PEFile::GetDebugName()
290 // ------------------------------------------------------------
292 // ------------------------------------------------------------
294 inline BOOL PEFile::IsAssembly() const
296 LIMITED_METHOD_DAC_CONTRACT;
298 return (m_flags & PEFILE_ASSEMBLY) != 0;
301 inline PTR_PEAssembly PEFile::AsAssembly()
303 LIMITED_METHOD_DAC_CONTRACT;
306 return dac_cast<PTR_PEAssembly>(nullptr);
308 return dac_cast<PTR_PEAssembly>(this);
310 return dac_cast<PTR_PEAssembly>(nullptr);
313 inline BOOL PEFile::IsModule() const
315 LIMITED_METHOD_CONTRACT;
318 return (m_flags & PEFILE_MODULE) != 0;
321 inline PTR_PEModule PEFile::AsModule()
323 LIMITED_METHOD_DAC_CONTRACT;
326 return dac_cast<PTR_PEModule>(nullptr);
328 return dac_cast<PTR_PEModule>(this);
330 return dac_cast<PTR_PEModule>(nullptr);
333 inline BOOL PEFile::IsSystem() const
335 LIMITED_METHOD_CONTRACT;
338 return (m_flags & PEFILE_SYSTEM) != 0;
341 inline BOOL PEFile::IsDynamic() const
343 LIMITED_METHOD_CONTRACT;
346 return m_identity == NULL;
349 inline BOOL PEFile::IsResource() const
354 #ifdef FEATURE_MULTIMODULE_ASSEMBLIES
355 return IsModule() && dac_cast<PTR_PEModule>(this)->IsResource();
358 #endif // FEATURE_MULTIMODULE_ASSEMBLIES
361 inline BOOL PEFile::IsIStream() const
363 LIMITED_METHOD_CONTRACT;
365 return (m_flags & PEFILE_ISTREAM) != 0;
368 inline BOOL PEFile::IsIntrospectionOnly() const
371 STATIC_CONTRACT_SO_TOLERANT;
372 #ifdef FEATURE_MULTIMODULE_ASSEMBLIES
375 return dac_cast<PTR_PEModule>(this)->GetAssembly()->IsIntrospectionOnly();
378 #endif // FEATURE_MULTIMODULE_ASSEMBLIES
380 return (m_flags & PEFILE_INTROSPECTIONONLY) != 0;
385 inline PEAssembly *PEFile::GetAssembly() const
388 #ifdef FEATURE_MULTIMODULE_ASSEMBLIES
390 return dac_cast<PTR_PEAssembly>(this);
392 return dac_cast<PTR_PEModule>(this)->GetAssembly();
394 _ASSERTE(IsAssembly());
395 return dac_cast<PTR_PEAssembly>(this);
397 #endif // FEATURE_MULTIMODULE_ASSEMBLIES
400 // ------------------------------------------------------------
402 // ------------------------------------------------------------
404 #ifndef DACCESS_COMPILE
405 inline void PEFile::GetImageBits(SBuffer &result)
410 PRECONDITION(CheckValue(result));
418 // We don't cache any other hashes right now.
420 GetILimage()->GetImageBits(PEImageLayout::LAYOUT_FLAT,result);
423 inline void PEFile::GetHash(ALG_ID algorithm, SBuffer &result)
428 PRECONDITION(CheckValue(result));
435 if (algorithm == CALG_SHA1)
442 // We don't cache any other hashes right now.
443 GetILimage()->ComputeHash(algorithm, result);
447 inline CHECK PEFile::CheckHash(ALG_ID algorithm, const void *hash, COUNT_T size)
452 PRECONDITION(CheckPointer(hash));
459 StackSBuffer hashBuffer;
460 GetHash(algorithm, hashBuffer);
462 CHECK(hashBuffer.Equals((const BYTE *)hash, size));
466 #endif // DACCESS_COMPILE
468 // ------------------------------------------------------------
470 // ------------------------------------------------------------
472 inline BOOL PEFile::HasMetadata()
484 return !IsResource();
487 inline IMDInternalImportHolder PEFile::GetMDImport()
490 if (m_bHasPersistentMDImport)
491 return IMDInternalImportHolder(GetPersistentMDImport(),FALSE);
493 return IMDInternalImportHolder(GetMDImportWithRef(),TRUE);
496 inline IMDInternalImport* PEFile::GetPersistentMDImport()
499 CONTRACT(IMDInternalImport *)
502 PRECONDITION(!IsResource());
503 POSTCONDITION(CheckPointer(RETVAL));
511 #if !defined(__GNUC__)
513 _ASSERTE(!IsResource());
515 #ifdef DACCESS_COMPILE
517 return DacGetMDImport(this, true);
519 LIMITED_METHOD_CONTRACT;
525 inline IMDInternalImport *PEFile::GetMDImportWithRef()
528 CONTRACT(IMDInternalImport *)
531 PRECONDITION(!IsResource());
532 POSTCONDITION(CheckPointer(RETVAL));
540 #if !defined(__GNUC__)
541 _ASSERTE(!IsResource());
543 #ifdef DACCESS_COMPILE
545 return DacGetMDImport(this, true);
550 WRAPPER(GC_TRIGGERS);
558 SimpleReadLockHolder lock(m_pMetadataLock);
560 m_pMDImport->AddRef();
565 #ifndef DACCESS_COMPILE
567 inline IMetaDataImport2 *PEFile::GetRWImporter()
569 CONTRACT(IMetaDataImport2 *)
572 PRECONDITION(!IsResource());
573 POSTCONDITION(CheckPointer(RETVAL));
574 PRECONDITION(m_bHasPersistentMDImport);
581 if (m_pImporter == NULL)
587 inline IMetaDataEmit *PEFile::GetEmitter()
589 CONTRACT(IMetaDataEmit *)
594 PRECONDITION(!IsResource());
595 POSTCONDITION(CheckPointer(RETVAL));
596 PRECONDITION(m_bHasPersistentMDImport);
601 if (m_pEmitter == NULL)
608 #endif // DACCESS_COMPILE
610 // The simple name is not actually very simple. The name returned comes from one of
611 // various metadata tables, depending on whether this is a manifest module,
612 // non-manifest module, or something else
613 inline LPCUTF8 PEFile::GetSimpleName()
619 POSTCONDITION(CheckPointer(RETVAL));
622 WRAPPER(GC_TRIGGERS);
627 RETURN dac_cast<PTR_PEAssembly>(this)->GetSimpleName();
628 #ifdef FEATURE_MULTIMODULE_ASSEMBLIES
630 RETURN dac_cast<PTR_PEModule>(this)->GetSimpleName();
631 #endif // FEATURE_MULTIMODULE_ASSEMBLIES
635 if (FAILED(GetScopeName(&szScopeName)))
644 // Same as the managed Module.ScopeName property, this unconditionally looks in the
645 // metadata Module table to get the name. Useful for profilers and others who don't
646 // like sugar coating on their names.
647 inline HRESULT PEFile::GetScopeName(LPCUTF8 * pszName)
659 return GetMDImport()->GetScopeProps(pszName, NULL);
663 // ------------------------------------------------------------
665 // ------------------------------------------------------------
667 inline BOOL PEFile::HasSecurityDirectory()
671 if (IsResource() || IsDynamic())
674 #ifdef FEATURE_PREJIT
675 if (IsNativeLoaded())
677 CONSISTENCY_CHECK(HasNativeImage());
679 return m_nativeImage->GetNativeILHasSecurityDirectory();
681 #ifndef DACCESS_COMPILE
682 if (!HasOpenedILimage())
684 //don't want to touch the IL image unless we already have
685 ReleaseHolder<PEImage> pNativeImage = GetNativeImageWithRef();
687 return pNativeImage->GetNativeILHasSecurityDirectory();
689 #endif // DACCESS_COMPILE
690 #endif // FEATURE_PREJIT
692 if (!GetILimage()->HasNTHeaders())
695 return GetOpenedILimage()->HasDirectoryEntry(IMAGE_DIRECTORY_ENTRY_SECURITY);
698 inline BOOL PEFile::IsIbcOptimized()
702 #ifdef FEATURE_PREJIT
703 if (IsNativeLoaded())
705 CONSISTENCY_CHECK(HasNativeImage());
707 return m_nativeImage->IsIbcOptimized();
714 inline BOOL PEFile::IsILImageReadyToRun()
725 #ifdef FEATURE_PREJIT
726 if (IsNativeLoaded())
728 CONSISTENCY_CHECK(HasNativeImage());
730 return GetLoadedNative()->GetNativeILHasReadyToRunHeader();
733 #endif // FEATURE_PREJIT
734 if (HasOpenedILimage())
736 return GetLoadedIL()->HasReadyToRunHeader();
744 inline WORD PEFile::GetSubsystem()
748 if (IsResource() || IsDynamic())
751 #ifdef FEATURE_PREJIT
752 if (IsNativeLoaded())
754 CONSISTENCY_CHECK(HasNativeImage());
756 return GetLoadedNative()->GetSubsystem();
758 #ifndef DACCESS_COMPILE
759 if (!HasOpenedILimage())
761 //don't want to touch the IL image unless we already have
762 ReleaseHolder<PEImage> pNativeImage = GetNativeImageWithRef();
764 return pNativeImage->GetSubsystem();
766 #endif // DACCESS_COMPILE
767 #endif // FEATURE_PREJIT
769 return GetLoadedIL()->GetSubsystem();
772 inline mdToken PEFile::GetEntryPointToken(
780 if (IsResource() || IsDynamic())
784 #ifdef FEATURE_PREJIT
785 if (IsNativeLoaded())
787 CONSISTENCY_CHECK(HasNativeImage());
788 _ASSERTE (!bAssumeLoaded || m_nativeImage->HasLoadedLayout ());
789 return m_nativeImage->GetEntryPointToken();
791 #ifndef DACCESS_COMPILE
792 if (!HasOpenedILimage())
794 //don't want to touch the IL image unless we already have
795 ReleaseHolder<PEImage> pNativeImage = GetNativeImageWithRef();
797 _ASSERTE (!bAssumeLoaded || pNativeImage->HasLoadedLayout ());
798 return pNativeImage->GetEntryPointToken();
801 #endif // DACCESS_COMPILE
802 #endif // FEATURE_PREJIT
803 _ASSERTE (!bAssumeLoaded || HasLoadedIL ());
804 return GetOpenedILimage()->GetEntryPointToken();
807 #ifdef FEATURE_PREJIT
808 inline BOOL PEFile::IsNativeLoaded()
811 return (m_nativeImage && m_bHasPersistentMDImport && m_nativeImage->HasLoadedLayout());
813 inline void PEFile::MarkNativeImageInvalidIfOwned()
816 // If owned, mark the PEFile as dummy, so the image does not get reused
817 PEImageHolder nativeImage(GetNativeImageWithRef());
818 Module * pNativeModule = nativeImage->GetLoadedLayout()->GetPersistedModuleImage();
819 PEFile ** ppNativeFile = (PEFile**) (PBYTE(pNativeModule) + Module::GetFileOffset());
821 // Attempt to write only if we claimed the ownership.
822 if (*ppNativeFile == this)
823 FastInterlockCompareExchangePointer(ppNativeFile, Dummy(), this);
829 inline BOOL PEFile::IsILOnly()
831 STATIC_CONTRACT_SO_TOLERANT;
835 CONTRACT_VIOLATION(ThrowsViolation|GCViolation|FaultViolation);
837 if (IsResource() || IsDynamic())
840 #ifdef FEATURE_PREJIT
841 if (IsNativeLoaded())
843 CONSISTENCY_CHECK(HasNativeImage());
845 return m_nativeImage->IsNativeILILOnly();
847 #ifndef DACCESS_COMPILE
848 if (!HasOpenedILimage())
852 BEGIN_SO_INTOLERANT_CODE(GetThread());
854 //don't want to touch the IL image unless we already have
855 ReleaseHolder<PEImage> pNativeImage = GetNativeImageWithRef();
858 retVal = pNativeImage->IsNativeILILOnly();
861 END_SO_INTOLERANT_CODE;
865 #endif // DACCESS_COMPILE
866 #endif // FEATURE_PREJIT
868 return GetOpenedILimage()->IsILOnly();
871 inline BOOL PEFile::IsDll()
875 if (IsResource() || IsDynamic())
878 #ifdef FEATURE_PREJIT
879 if (IsNativeLoaded())
881 CONSISTENCY_CHECK(HasNativeImage());
883 return m_nativeImage->IsNativeILDll();
885 #ifndef DACCESS_COMPILE
886 if (!HasOpenedILimage())
888 //don't want to touch the IL image unless we already have
889 ReleaseHolder<PEImage> pNativeImage =GetNativeImageWithRef();
891 return pNativeImage->IsNativeILDll();
894 #endif // DACCESS_COMPILE
895 #endif // FEATURE_PREJIT
897 return GetOpenedILimage()->IsDll();
900 inline PTR_VOID PEFile::GetRvaField(RVA field)
905 PRECONDITION(!IsDynamic());
906 PRECONDITION(!IsResource());
907 PRECONDITION(CheckRvaField(field));
908 PRECONDITION(CheckLoaded());
913 POSTCONDITION(CheckPointer(RETVAL));
917 // Note that the native image Rva fields are currently cut off before
918 // this point. We should not get here for an IL only native image.
920 RETURN dac_cast<PTR_VOID>(GetLoadedIL()->GetRvaData(field,NULL_OK));
923 inline CHECK PEFile::CheckRvaField(RVA field)
928 PRECONDITION(!IsDynamic());
929 PRECONDITION(!IsResource());
930 PRECONDITION(CheckLoaded());
937 // Note that the native image Rva fields are currently cut off before
938 // this point. We should not get here for an IL only native image.
940 CHECK(GetLoadedIL()->CheckRva(field,NULL_OK));
944 inline CHECK PEFile::CheckRvaField(RVA field, COUNT_T size)
949 PRECONDITION(!IsDynamic());
950 PRECONDITION(!IsResource());
951 PRECONDITION(CheckLoaded());
958 // Note that the native image Rva fields are currently cut off before
959 // this point. We should not get here for an IL only native image.
961 CHECK(GetLoadedIL()->CheckRva(field, size,0,NULL_OK));
965 inline BOOL PEFile::HasTls()
973 PRECONDITION(CheckLoaded());
977 // Resource modules do not contain TLS data.
980 // Dynamic modules do not contain TLS data.
981 else if (IsDynamic())
983 // ILOnly modules do not contain TLS data.
987 return GetLoadedIL()->HasTls();
990 inline BOOL PEFile::IsRvaFieldTls(RVA field)
998 PRECONDITION(CheckLoaded());
1005 PTR_VOID address = PTR_VOID(GetLoadedIL()->GetRvaData(field));
1008 PTR_VOID tlsRange = GetLoadedIL()->GetTlsRange(&tlsSize);
1010 return (address >= tlsRange
1011 && address < (dac_cast<PTR_BYTE>(tlsRange)+tlsSize));
1014 inline UINT32 PEFile::GetFieldTlsOffset(RVA field)
1019 PRECONDITION(CheckRvaField(field));
1020 PRECONDITION(IsRvaFieldTls(field));
1021 PRECONDITION(CheckLoaded());
1028 return (UINT32)(dac_cast<PTR_BYTE>(GetRvaField(field)) -
1029 dac_cast<PTR_BYTE>(GetLoadedIL()->GetTlsRange()));
1032 inline UINT32 PEFile::GetTlsIndex()
1036 PRECONDITION(CheckLoaded());
1038 PRECONDITION(HasTls());
1045 return GetLoadedIL()->GetTlsIndex();
1048 inline const void *PEFile::GetInternalPInvokeTarget(RVA target)
1053 PRECONDITION(!IsDynamic());
1054 PRECONDITION(!IsResource());
1055 PRECONDITION(CheckInternalPInvokeTarget(target));
1056 PRECONDITION(CheckLoaded());
1060 POSTCONDITION(CheckPointer(RETVAL));
1064 RETURN (void*)GetLoadedIL()->GetRvaData(target);
1067 inline CHECK PEFile::CheckInternalPInvokeTarget(RVA target)
1072 PRECONDITION(!IsDynamic());
1073 PRECONDITION(!IsResource());
1074 PRECONDITION(CheckLoaded());
1082 CHECK(GetLoadedIL()->CheckRva(target));
1087 inline PCCOR_SIGNATURE PEFile::GetSignature(RVA signature)
1089 CONTRACT(PCCOR_SIGNATURE)
1092 PRECONDITION(!IsDynamic() || signature == 0);
1093 PRECONDITION(!IsResource());
1094 PRECONDITION(CheckSignatureRva(signature));
1095 POSTCONDITION(CheckSignature(RETVAL));
1096 PRECONDITION(CheckLoaded());
1106 RETURN (PCCOR_SIGNATURE) GetLoadedIL()->GetRvaData(signature);
1109 inline RVA PEFile::GetSignatureRva(PCCOR_SIGNATURE signature)
1114 PRECONDITION(!IsDynamic() || signature == NULL);
1115 PRECONDITION(!IsResource());
1116 PRECONDITION(CheckSignature(signature));
1117 POSTCONDITION(CheckSignatureRva(RETVAL));
1118 PRECONDITION(CheckLoaded());
1125 if (signature == NULL)
1128 RETURN GetLoadedIL()->GetDataRva(
1129 dac_cast<TADDR>(signature));
1132 inline CHECK PEFile::CheckSignature(PCCOR_SIGNATURE signature)
1137 PRECONDITION(!IsDynamic() || signature == NULL);
1138 PRECONDITION(!IsResource());
1139 PRECONDITION(CheckLoaded());
1146 CHECK(GetLoadedIL()->CheckData(signature,NULL_OK));
1150 inline CHECK PEFile::CheckSignatureRva(RVA signature)
1155 PRECONDITION(!IsDynamic() || signature == NULL);
1156 PRECONDITION(!IsResource());
1157 PRECONDITION(CheckLoaded());
1164 CHECK(GetLoadedIL()->CheckRva(signature,NULL_OK));
1168 inline IMAGE_COR_VTABLEFIXUP *PEFile::GetVTableFixups(COUNT_T *pCount/*=NULL*/)
1170 CONTRACT(IMAGE_COR_VTABLEFIXUP *)
1172 PRECONDITION(CheckLoaded());
1177 POSTCONDITION(CheckPointer(RETVAL, NULL_OK));
1181 if (IsResource() || IsDynamic() || IsILOnly())
1188 RETURN GetLoadedIL()->GetVTableFixups(pCount);
1191 inline void *PEFile::GetVTable(RVA rva)
1196 PRECONDITION(!IsDynamic());
1197 PRECONDITION(!IsResource());
1198 PRECONDITION(CheckLoaded());
1199 PRECONDITION(!IsILOnly());
1200 PRECONDITION(GetLoadedIL()->CheckRva(rva));
1204 POSTCONDITION(CheckPointer(RETVAL));
1208 RETURN (void *)GetLoadedIL()->GetRvaData(rva);
1211 // @todo: this is bad to expose. But it is needed to support current IJW thunks
1212 inline HMODULE PEFile::GetIJWBase()
1217 PRECONDITION(!IsDynamic());
1218 PRECONDITION(!IsResource());
1219 PRECONDITION(CheckLoaded());
1220 PRECONDITION(!IsILOnly());
1227 return (HMODULE) dac_cast<TADDR>(GetLoadedIL()->GetBase());
1230 inline PTR_VOID PEFile::GetDebuggerContents(COUNT_T *pSize/*=NULL*/)
1235 PRECONDITION(CheckPointer(pSize, NULL_OK));
1237 WRAPPER(GC_TRIGGERS);
1239 POSTCONDITION(CheckPointer(RETVAL, NULL_OK));
1243 // We cannot in general force a LoadLibrary; we might be in the
1244 // helper thread. The debugger will have to expect a zero base
1245 // in some circumstances.
1250 *pSize = GetLoaded()->GetSize();
1252 RETURN GetLoaded()->GetBase();
1263 inline PTR_CVOID PEFile::GetLoadedImageContents(COUNT_T *pSize/*=NULL*/)
1275 if (IsLoaded() && !IsDynamic())
1279 *pSize = GetLoaded()->GetSize();
1281 return GetLoaded()->GetBase();
1293 #ifndef DACCESS_COMPILE
1294 inline const void *PEFile::GetManagedFileContents(COUNT_T *pSize/*=NULL*/)
1296 CONTRACT(const void *)
1299 PRECONDITION(CheckLoaded());
1301 WRAPPER(GC_TRIGGERS);
1303 POSTCONDITION((!GetLoaded()->GetSize()) || CheckPointer(RETVAL));
1307 // Right now, we will trigger a LoadLibrary for the caller's sake,
1308 // even if we are in a scenario where we could normally avoid it.
1312 *pSize = GetLoadedIL()->GetSize();
1315 RETURN GetLoadedIL()->GetBase();
1317 #endif // DACCESS_COMPILE
1319 inline BOOL PEFile::IsPtrInILImage(PTR_CVOID data)
1332 if (HasOpenedILimage())
1334 #if defined(FEATURE_PREJIT)
1335 if (m_openedILimage == m_nativeImage)
1337 // On Apollo builds, we sometimes open the native image into the slot
1338 // normally reserved for the IL image (as the IL image is often not available
1339 // on the disk at all). In such a case, data is not coming directly from an
1340 // actual IL image, but see if it's coming from the metadata that we copied
1341 // from the IL image into the NI.
1342 TADDR taddrData = dac_cast<TADDR>(data);
1343 PEDecoder * pDecoder = m_nativeImage->GetLoadedLayout();
1344 COUNT_T cbILMetadata;
1345 TADDR taddrILMetadata = dac_cast<TADDR>(pDecoder->GetMetadata(&cbILMetadata));
1346 return ((taddrILMetadata <= taddrData) && (taddrData < taddrILMetadata + cbILMetadata));
1348 #endif // defined(FEATURE_PREJIT) && defined(FEATURE_CORECLR)
1349 return GetOpenedILimage()->IsPtrInImage(data);
1354 // ------------------------------------------------------------
1355 // Native image access
1356 // ------------------------------------------------------------
1357 inline BOOL PEFile::HasNativeImage()
1371 #ifdef FEATURE_PREJIT
1372 return (m_nativeImage != NULL);
1378 inline PTR_PEImageLayout PEFile::GetLoadedIL()
1380 LIMITED_METHOD_CONTRACT;
1383 _ASSERTE(HasOpenedILimage());
1384 if(IsIntrospectionOnly())
1385 return GetOpenedILimage()->GetLoadedIntrospectionLayout();
1387 return GetOpenedILimage()->GetLoadedLayout();
1390 inline PTR_PEImageLayout PEFile::GetAnyILWithRef()
1392 WRAPPER_NO_CONTRACT;
1393 return GetILimage()->GetLayout(PEImageLayout::LAYOUT_ANY,PEImage::LAYOUT_CREATEIFNEEDED);
1397 inline BOOL PEFile::IsLoaded(BOOL bAllowNative/*=TRUE*/)
1409 if(IsIntrospectionOnly())
1411 return HasOpenedILimage() && GetOpenedILimage()->HasLoadedIntrospectionLayout();
1413 #ifdef FEATURE_PREJIT
1414 if (bAllowNative && HasNativeImage())
1416 PEImage *pNativeImage = GetPersistentNativeImage();
1417 return pNativeImage->HasLoadedLayout() && (pNativeImage->GetLoadedLayout()->IsNativeILILOnly() || (HasLoadedIL()));
1421 return HasLoadedIL();
1425 inline PTR_PEImageLayout PEFile::GetLoaded()
1427 WRAPPER_NO_CONTRACT;
1429 return HasNativeImage()?GetLoadedNative():GetLoadedIL();
1432 inline PTR_PEImageLayout PEFile::GetLoadedNative()
1444 #ifdef FEATURE_PREJIT
1445 PEImage* pImage=GetPersistentNativeImage();
1446 _ASSERTE(pImage && pImage->GetLoadedLayout());
1447 return pImage->GetLoadedLayout();
1449 // Should never get here
1450 PRECONDITION(HasNativeImage());
1455 #ifdef FEATURE_PREJIT
1456 inline PEImage *PEFile::GetPersistentNativeImage()
1461 PRECONDITION(HasNativeImage());
1462 POSTCONDITION(CheckPointer(RETVAL));
1463 PRECONDITION(m_bHasPersistentMDImport);
1473 RETURN m_nativeImage;
1476 #ifndef DACCESS_COMPILE
1477 inline PEImage *PEFile::GetNativeImageWithRef()
1485 POSTCONDITION(CheckPointer(RETVAL,NULL_OK));
1489 SimpleReadLockHolder mdlock(m_pMetadataLock);
1491 m_nativeImage->AddRef();
1492 RETURN m_nativeImage;
1494 #endif // DACCESS_COMPILE
1496 inline BOOL PEFile::HasNativeImageMetadata()
1509 RETURN ((m_flags & PEFILE_HAS_NATIVE_IMAGE_METADATA) != 0);
1513 // Function to get the fully qualified name of an assembly
1514 inline void PEAssembly::GetFullyQualifiedAssemblyName(IMDInternalImport* pImport, mdAssembly mda, SString &result, DWORD flags)
1518 PRECONDITION(CheckValue(result));
1519 #ifndef DACCESS_COMPILE
1523 #endif // !DACCESS_COMPILE
1531 // This is for DAC, ONLY for the binding tool. Don't use for other
1532 // purposes, since this is not canonicalized through Fusion.
1534 AssemblyMetaDataInternal context;
1538 if (FAILED(pImport->GetAssemblyProps(
1540 (const void **) &pbPublicKey,
1547 _ASSERTE(!"If this fires, then we have to throw for corrupted images");
1552 result.SetUTF8(name);
1554 result.AppendPrintf(W(", Version=%u.%u.%u.%u"),
1555 context.usMajorVersion, context.usMinorVersion,
1556 context.usBuildNumber, context.usRevisionNumber);
1558 result.Append(W(", Culture="));
1559 if (!*context.szLocale)
1561 result.Append(W("neutral"));
1565 result.AppendUTF8(context.szLocale);
1568 if (cbPublicKey != 0)
1570 #ifndef DACCESS_COMPILE
1572 StrongNameBufferHolder<BYTE> pbToken;
1576 if (StrongNameTokenFromPublicKey(pbPublicKey, cbPublicKey,
1577 &pbToken, &cbToken))
1579 // two hex digits per byte
1580 WCHAR* szToken = (WCHAR*) qb.AllocNoThrow(sizeof(WCHAR) * (cbToken*2+1));
1583 #define TOHEX(a) ((a)>=10 ? L'a'+(a)-10 : L'0'+(a))
1586 for ( x = 0, y = 0; x < cbToken; ++x )
1588 WCHAR v = static_cast<WCHAR>(pbToken[x] >> 4);
1589 szToken[y++] = TOHEX( v );
1590 v = static_cast<WCHAR>(pbToken[x] & 0x0F);
1591 szToken[y++] = TOHEX( v );
1595 result.Append(W(", PublicKeyToken="));
1596 result.Append(szToken);
1605 result.Append(W(", PublicKeyToken=null"));
1608 if (dwFlags & afPA_Mask)
1610 result.Append(W(", ProcessorArchitecture="));
1612 if (dwFlags & afPA_MSIL)
1613 result.Append(W("MSIL"));
1614 else if (dwFlags & afPA_x86)
1615 result.Append(W("x86"));
1616 else if (dwFlags & afPA_IA64)
1617 result.Append(W("IA64"));
1618 else if (dwFlags & afPA_AMD64)
1619 result.Append(W("AMD64"));
1620 else if (dwFlags & afPA_ARM)
1621 result.Append(W("ARM"));
1627 // ------------------------------------------------------------
1628 // Descriptive strings
1629 // ------------------------------------------------------------
1630 inline void PEAssembly::GetDisplayName(SString &result, DWORD flags)
1634 PRECONDITION(CheckValue(result));
1635 #ifndef DACCESS_COMPILE
1639 #endif // DACCESS_COMPILE
1645 #ifndef DACCESS_COMPILE
1647 #ifdef FEATURE_FUSION
1648 FusionBind::GetAssemblyNameDisplayName(GetFusionAssemblyName(), result, flags);
1650 if ((flags == (ASM_DISPLAYF_VERSION | ASM_DISPLAYF_CULTURE | ASM_DISPLAYF_PUBLIC_KEY_TOKEN)) &&
1651 !m_sTextualIdentity.IsEmpty())
1653 result.Set(m_sTextualIdentity);
1658 spec.InitializeSpec(this);
1659 spec.GetFileOrDisplayName(flags, result);
1661 #endif // FEATURE_FUSION
1664 IMDInternalImport *pImport = GetMDImport();
1665 GetFullyQualifiedAssemblyName(pImport, TokenFromRid(1, mdtAssembly), result, flags);
1666 #endif //DACCESS_COMPILE
1669 // ------------------------------------------------------------
1671 // ------------------------------------------------------------
1673 inline LPCSTR PEAssembly::GetSimpleName()
1678 if (!m_bHasPersistentMDImport) { GC_TRIGGERS;} else {DISABLED(GC_TRIGGERS);};
1685 IMDInternalImportHolder pImport = GetMDImport();
1686 if (pImport != NULL)
1688 if (FAILED(pImport->GetAssemblyProps(TokenFromRid(1, mdtAssembly), NULL, NULL, NULL, &name, NULL, NULL)))
1690 _ASSERTE(!"If this fires, then we have to throw for corrupted images");
1697 inline BOOL PEFile::IsStrongNamed()
1702 WRAPPER(GC_NOTRIGGER);
1708 IfFailThrow(GetMDImport()->GetAssemblyProps(TokenFromRid(1, mdtAssembly), NULL, NULL, NULL, NULL, NULL, &flags));
1709 return (flags & afPublicKey) != NULL;
1713 //---------------------------------------------------------------------------------------
1715 // Check to see if this assembly has had its strong name signature verified yet.
1718 inline BOOL PEFile::IsStrongNameVerified()
1720 LIMITED_METHOD_CONTRACT;
1721 return m_fStrongNameVerified;
1724 inline const void *PEFile::GetPublicKey(DWORD *pcbPK)
1728 PRECONDITION(CheckPointer(pcbPK, NULL_OK));
1730 WRAPPER(GC_TRIGGERS);
1736 IfFailThrow(GetMDImport()->GetAssemblyProps(TokenFromRid(1, mdtAssembly), &pPK, pcbPK, NULL, NULL, NULL, NULL));
1740 inline ULONG PEFile::GetHashAlgId()
1745 WRAPPER(GC_TRIGGERS);
1751 IfFailThrow(GetMDImport()->GetAssemblyProps(TokenFromRid(1, mdtAssembly), NULL, NULL, &hashAlgId, NULL, NULL, NULL));
1755 inline LPCSTR PEFile::GetLocale()
1760 WRAPPER(GC_NOTRIGGER);
1765 AssemblyMetaDataInternal md;
1766 IfFailThrow(GetMDImport()->GetAssemblyProps(TokenFromRid(1, mdtAssembly), NULL, NULL, NULL, NULL, &md, NULL));
1770 inline DWORD PEFile::GetFlags()
1774 PRECONDITION(IsAssembly());
1776 if (FORBIDGC_LOADER_USE_ENABLED()) NOTHROW; else THROWS;
1777 if (FORBIDGC_LOADER_USE_ENABLED()) GC_NOTRIGGER; else GC_TRIGGERS;
1778 if (FORBIDGC_LOADER_USE_ENABLED()) FORBID_FAULT; else { INJECT_FAULT(COMPlusThrowOM()); }
1784 IfFailThrow(GetMDImport()->GetAssemblyProps(TokenFromRid(1, mdtAssembly), NULL, NULL, NULL, NULL, NULL, &flags));
1788 // In the cases where you know the module is loaded, and cannot tolerate triggering and
1789 // loading, this alternative to PEFile::GetFlags is useful. Profiling API uses this.
1790 inline HRESULT PEFile::GetFlagsNoTrigger(DWORD * pdwFlags)
1794 PRECONDITION(IsAssembly());
1803 _ASSERTE (pdwFlags != NULL);
1805 if (!m_bHasPersistentMDImport)
1808 return GetPersistentMDImport()->GetAssemblyProps(TokenFromRid(1, mdtAssembly), NULL, NULL, NULL, NULL, NULL, pdwFlags);
1811 #ifdef FEATURE_CAS_POLICY
1812 inline COR_TRUST *PEFile::GetAuthenticodeSignature()
1822 if (!m_fCheckedCertificate && HasSecurityDirectory())
1824 CheckAuthenticodeSignature();
1827 return m_certificate;
1831 // ------------------------------------------------------------
1833 // ------------------------------------------------------------
1835 inline BOOL PEAssembly::HasStrongNameSignature()
1837 WRAPPER_NO_CONTRACT;
1842 #ifdef FEATURE_PREJIT
1843 if (IsNativeLoaded())
1845 CONSISTENCY_CHECK(HasNativeImage());
1847 // The NGen images do not have strong name signature
1850 #endif // FEATURE_PREJIT
1852 return GetILimage()->HasStrongNameSignature();
1855 //---------------------------------------------------------------------------------------
1857 // Check to see that an assembly is not delay or test signed
1860 inline BOOL PEAssembly::IsFullySigned()
1862 WRAPPER_NO_CONTRACT;
1864 #ifdef FEATURE_PREJIT
1865 if (IsNativeLoaded())
1867 CONSISTENCY_CHECK(HasNativeImage());
1869 // If we are strongly named and successfully strong named, then we consider ourselves fully
1870 // signed since either our signature verified at ngen time, or skip verification was in effect
1871 // The only code that differentiates between skip verification and fully signed is in the strong
1872 // name verification path itself, and therefore we abstract that away at this level.
1874 // Note that this is consistent with other abstractions at the PEFile level such as
1875 // HasStrongNameSignature()
1876 return IsStrongNamed();
1878 #endif // FEATURE_PREJIT
1879 if (HasOpenedILimage())
1881 return GetOpenedILimage()->IsStrongNameSigned();
1890 #ifdef FEATURE_CAS_POLICY
1891 //---------------------------------------------------------------------------------------
1893 // Verify the Authenticode and strong name signatures of an assembly during the assembly
1894 // load code path. To verify the strong name signature outside of assembly load, use the
1895 // VefifyStrongName method instead.
1897 // If the applicaiton is using strong name bypass, then this method may not cause a real
1898 // strong name verification, delaying the assembly's strong name load until we know that
1899 // the verification is required. If the assembly must be forced to have its strong name
1900 // verified, then the VerifyStrongName method should also be chosen.
1902 // See code:AssemblySecurityDescriptor::ResolveWorker#StrongNameBypass
1905 inline void PEAssembly::DoLoadSignatureChecks()
1910 GC_TRIGGERS; // Fusion uses crsts on AddRef/Release
1915 ETWOnStartup(SecurityCatchCall_V1, SecurityCatchCallEnd_V1);
1917 // If this isn't mscorlib or a dynamic assembly, verify the Authenticode signature.
1918 if (IsSystem() || IsDynamic())
1920 // If it was a dynamic module (or mscorlib), then we don't want to be doing module hash checks on it
1921 m_flags |= PEFILE_SKIP_MODULE_HASH_CHECKS;
1924 // Check strong name signature. We only want to do this now if the application is not using the strong
1925 // name bypass feature. Otherwise we'll delay strong name verification until we figure out how trusted
1928 // For more information see code:AssemblySecurityDescriptor::ResolveWorker#StrongNameBypass
1930 // Make sure m_pMDImport is initialized as we need to call VerifyStrongName which calls GetFlags
1931 // BypassTrustedAppStrongNames = false is a relatively uncommon scenario so we need to make sure
1932 // the initialization order is always correct and we don't miss this uncommon case
1933 _ASSERTE(GetMDImport());
1935 if (!g_pConfig->BypassTrustedAppStrongNames())
1940 #endif // FEATURE_CAS_POLICY
1942 // ------------------------------------------------------------
1944 // ------------------------------------------------------------
1945 #ifdef FEATURE_MULTIMODULE_ASSEMBLIES
1946 inline PEAssembly *PEModule::GetAssembly()
1948 CONTRACT(PEAssembly *)
1950 POSTCONDITION(CheckPointer(RETVAL));
1963 inline BOOL PEModule::IsResource()
1974 #ifdef DACCESS_COMPILE
1975 _ASSERTE(m_bIsResource!=-1);
1977 if (m_bIsResource==-1)
1980 if (FAILED(m_assembly->GetPersistentMDImport()->GetFileProps(m_token, NULL, NULL, NULL, &flags)))
1982 _ASSERTE(!"If this fires, then we have to throw for corrupted images");
1985 m_bIsResource=((flags & ffContainsNoMetaData) != 0);
1989 return m_bIsResource;
1992 inline LPCUTF8 PEModule::GetSimpleName()
1996 POSTCONDITION(CheckPointer(RETVAL));
1997 POSTCONDITION(strlen(RETVAL) > 0);
2008 if (FAILED(m_assembly->GetPersistentMDImport()->GetFileProps(m_token, &name, NULL, NULL, NULL)))
2010 _ASSERTE(!"If this fires, then we have to throw for corrupted images");
2017 inline mdFile PEModule::GetToken()
2019 LIMITED_METHOD_CONTRACT;
2022 #endif // FEATURE_MULTIMODULE_ASSEMBLIES
2024 #ifndef DACCESS_COMPILE
2025 inline void PEFile::RestoreMDImport(IMDInternalImport* pImport)
2036 _ASSERTE(m_pMetadataLock->LockTaken() && m_pMetadataLock->IsWriterLock());
2037 if (m_pMDImport != NULL)
2039 m_pMDImport=pImport;
2041 m_pMDImport->AddRef();
2044 inline void PEFile::OpenMDImport()
2046 WRAPPER_NO_CONTRACT;
2047 //need synchronization
2048 _ASSERTE(m_pMetadataLock->LockTaken() && m_pMetadataLock->IsWriterLock());
2049 OpenMDImport_Unsafe();
2052 inline PEFile* PEFile::Dummy()
2054 return (PEFile*)(-1);
2057 inline bool PEAssembly::HasBindableIdentity()
2062 if (FORBIDGC_LOADER_USE_ENABLED()) NOTHROW; else THROWS;
2063 if (FORBIDGC_LOADER_USE_ENABLED()) GC_NOTRIGGER; else GC_TRIGGERS;
2064 if (FORBIDGC_LOADER_USE_ENABLED()) FORBID_FAULT; else { INJECT_FAULT(COMPlusThrowOM()); }
2070 return !IsAfContentType_WindowsRuntime(GetFlags());
2073 inline bool PEAssembly::IsWindowsRuntime()
2083 return IsAfContentType_WindowsRuntime(GetFlags());
2086 #endif // PEFILE_INL_