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 // --------------------------------------------------------------------------------
14 #include "../dlls/mscorrc/resource.h"
16 inline ULONG PEImage::AddRef()
20 PRECONDITION(m_refCount>0 && m_refCount < COUNT_T_MAX);
26 RETURN (static_cast<ULONG>(FastInterlockIncrement(&m_refCount)));
29 inline const SString &PEImage::GetPath()
31 LIMITED_METHOD_DAC_CONTRACT;
32 STATIC_CONTRACT_SO_TOLERANT;
37 inline void PEImage::SetModuleFileNameHintForDAC()
39 LIMITED_METHOD_DAC_CONTRACT;
40 STATIC_CONTRACT_SO_INTOLERANT;
42 // Grab module name only for triage dumps where full paths are excluded
43 // because may contain PII data.
44 // m_sModuleFileNameHintUsedByDac will just point to module name starting character.
45 const WCHAR* pStartPath = m_path.GetUnicode();
46 COUNT_T nChars = m_path.GetCount();
47 if (pStartPath != NULL && nChars > 0 && nChars <= MAX_PATH)
49 const WCHAR* pChar = pStartPath + nChars;
51 while ((pChar >= pStartPath) && (*pChar != L'\\'))
57 m_sModuleFileNameHintUsedByDac.SetPreallocated(pChar, nChars);
61 #ifdef DACCESS_COMPILE
62 inline const SString &PEImage::GetModuleFileNameHintForDAC()
64 LIMITED_METHOD_CONTRACT;
66 return m_sModuleFileNameHintUsedByDac;
72 inline BOOL PEImage::IsFile()
76 return !m_path.IsEmpty();
79 #ifndef DACCESS_COMPILE
80 inline void PEImage::SetLayout(DWORD dwLayout, PEImageLayout* pLayout)
82 LIMITED_METHOD_CONTRACT;
83 _ASSERTE(dwLayout<IMAGE_COUNT);
84 _ASSERTE(m_pLayouts[dwLayout]==NULL);
85 FastInterlockExchangePointer((m_pLayouts+dwLayout),pLayout);
87 #endif // DACCESS_COMPILE
88 inline PTR_PEImageLayout PEImage::GetLoadedLayout()
90 LIMITED_METHOD_CONTRACT;
93 _ASSERTE(m_pLayouts[IMAGE_LOADED]!=NULL);
94 return m_pLayouts[IMAGE_LOADED]; //no addref
98 // GetExistingLayout - get an layout corresponding to the specified mask, or null if none.
99 // Does not take any locks or call AddRef.
102 // imageLayoutMask - bits from PEImageLayout specifying which layouts the caller would be
103 // interested in getting
106 // a PEImageLayout of a type matching one of the bits specified in the mask, or NULL if
107 // none exists yet. Does not call AddRef on the returned value.
109 inline PTR_PEImageLayout PEImage::GetExistingLayoutInternal(DWORD imageLayoutMask)
111 LIMITED_METHOD_CONTRACT;
114 PTR_PEImageLayout pRetVal = NULL;
116 if (imageLayoutMask&PEImageLayout::LAYOUT_LOADED)
117 pRetVal=m_pLayouts[IMAGE_LOADED];
118 if (pRetVal==NULL && (imageLayoutMask & PEImageLayout::LAYOUT_MAPPED))
119 pRetVal=m_pLayouts[IMAGE_MAPPED];
120 if (pRetVal==NULL && (imageLayoutMask & PEImageLayout::LAYOUT_FLAT))
121 pRetVal=m_pLayouts[IMAGE_FLAT];
127 inline BOOL PEImage::HasLoadedLayout()
129 LIMITED_METHOD_CONTRACT;
131 return m_pLayouts[IMAGE_LOADED]!=NULL;
134 inline BOOL PEImage::IsOpened()
136 LIMITED_METHOD_CONTRACT;
137 return m_pLayouts[IMAGE_LOADED]!=NULL ||m_pLayouts[IMAGE_MAPPED]!=NULL || m_pLayouts[IMAGE_FLAT] !=NULL;
141 #ifdef FEATURE_PREJIT
142 inline CHECK PEImage::CheckNativeFormat()
145 if (HasLoadedLayout())
146 CHECK(GetLoadedLayout()->CheckNativeFormat());
149 PEImageLayoutHolder pLayout(GetLayout(PEImageLayout::LAYOUT_ANY,LAYOUT_CREATEIFNEEDED));
150 CHECK(pLayout->CheckNativeFormat());
154 #endif // FEATURE_PREJIT
156 inline BOOL PEImage::IsReferenceAssembly()
160 PRECONDITION(HasCorHeader());
164 IMDInternalImport* mdImport = this->GetMDImport();
165 HRESULT hr = mdImport->GetCustomAttributeByName(TokenFromRid(1, mdtAssembly),
166 g_ReferenceAssemblyAttribute,
173 _ASSERTE(hr == S_FALSE);
178 inline const BOOL PEImage::HasNTHeaders()
181 if (HasLoadedLayout())
182 return GetLoadedLayout()->HasNTHeaders();
185 PEImageLayoutHolder pLayout(GetLayout(PEImageLayout::LAYOUT_ANY,LAYOUT_CREATEIFNEEDED));
186 return pLayout->HasNTHeaders();
190 inline const BOOL PEImage::HasCorHeader()
193 if (HasLoadedLayout())
194 return GetLoadedLayout()->HasCorHeader();
197 PEImageLayoutHolder pLayout(GetLayout(PEImageLayout::LAYOUT_ANY,LAYOUT_CREATEIFNEEDED));
198 return pLayout->HasCorHeader();
202 inline const BOOL PEImage::HasReadyToRunHeader()
205 if (HasLoadedLayout())
206 return GetLoadedLayout()->HasReadyToRunHeader();
209 PEImageLayoutHolder pLayout(GetLayout(PEImageLayout::LAYOUT_ANY,LAYOUT_CREATEIFNEEDED));
210 return pLayout->HasReadyToRunHeader();
214 inline void PEImage::SetPassiveDomainOnly()
216 LIMITED_METHOD_CONTRACT;
217 m_bPassiveDomainOnly=TRUE;
220 inline BOOL PEImage::PassiveDomainOnly()
222 LIMITED_METHOD_CONTRACT;
223 return m_bPassiveDomainOnly;
226 inline const BOOL PEImage::HasDirectoryEntry(int entry)
229 if (HasLoadedLayout())
230 return GetLoadedLayout()->HasDirectoryEntry(entry);
233 PEImageLayoutHolder pLayout(GetLayout(PEImageLayout::LAYOUT_ANY,LAYOUT_CREATEIFNEEDED));
234 return pLayout->HasDirectoryEntry(entry);
238 inline const mdToken PEImage::GetEntryPointToken()
241 if (HasLoadedLayout())
243 PTR_PEImageLayout pLayout = GetLoadedLayout();
244 if (!pLayout->HasManagedEntryPoint())
246 return pLayout->GetEntryPointToken();
250 PEImageLayoutHolder pLayout(GetLayout(PEImageLayout::LAYOUT_ANY,LAYOUT_CREATEIFNEEDED));
251 if (!pLayout->HasManagedEntryPoint())
253 return pLayout->GetEntryPointToken();
257 inline const DWORD PEImage::GetCorHeaderFlags()
261 if (HasLoadedLayout())
263 PTR_PEImageLayout pLayout = GetLoadedLayout();
264 return VAL32(pLayout->GetCorHeader()->Flags);
268 PEImageLayoutHolder pLayout(GetLayout(PEImageLayout::LAYOUT_ANY,LAYOUT_CREATEIFNEEDED));
269 return VAL32(pLayout->GetCorHeader()->Flags);
273 inline BOOL PEImage::MDImportLoaded()
275 return m_pMDImport != NULL;
278 inline const BOOL PEImage::HasV1Metadata()
281 return GetMDImport()->GetMetadataStreamVersion()==MD_STREAM_VER_1X;
284 inline const BOOL PEImage::IsILOnly()
287 if (HasLoadedLayout())
288 return GetLoadedLayout()->IsILOnly();
291 PEImageLayoutHolder pLayout(GetLayout(PEImageLayout::LAYOUT_ANY,LAYOUT_CREATEIFNEEDED));
292 return pLayout->IsILOnly();
296 inline const WORD PEImage::GetSubsystem()
301 if (HasLoadedLayout())
302 return GetLoadedLayout()->GetSubsystem();
305 PEImageLayoutHolder pLayout(GetLayout(PEImageLayout::LAYOUT_ANY,LAYOUT_CREATEIFNEEDED));
306 return pLayout->GetSubsystem();
310 #ifdef FEATURE_PREJIT
311 inline const BOOL PEImage::IsNativeILILOnly()
314 if (HasLoadedLayout())
315 return GetLoadedLayout()->IsNativeILILOnly();
318 PEImageLayoutHolder pLayout(GetLayout(PEImageLayout::LAYOUT_ANY,LAYOUT_CREATEIFNEEDED));
319 return pLayout->IsNativeILILOnly();
323 inline void PEImage::GetNativeILPEKindAndMachine(DWORD* pdwKind, DWORD* pdwMachine)
326 if (HasLoadedLayout())
327 GetLoadedLayout()->GetNativeILPEKindAndMachine(pdwKind, pdwMachine);
330 PEImageLayoutHolder pLayout(GetLayout(PEImageLayout::LAYOUT_ANY,LAYOUT_CREATEIFNEEDED));
331 pLayout->GetNativeILPEKindAndMachine(pdwKind, pdwMachine);
335 inline const BOOL PEImage::IsNativeILDll()
338 if (HasLoadedLayout())
339 return GetLoadedLayout()->IsNativeILDll();
342 PEImageLayoutHolder pLayout(GetLayout(PEImageLayout::LAYOUT_ANY,LAYOUT_CREATEIFNEEDED));
343 return pLayout->IsNativeILDll();
346 #endif // FEATURE_PREJIT
348 inline const BOOL PEImage::IsDll()
351 if (HasLoadedLayout())
352 return GetLoadedLayout()->IsDll();
355 PEImageLayoutHolder pLayout(GetLayout(PEImageLayout::LAYOUT_ANY,LAYOUT_CREATEIFNEEDED));
356 return pLayout->IsDll();
360 inline const BOOL PEImage::HasStrongNameSignature()
363 if (HasLoadedLayout())
364 return GetLoadedLayout()->HasStrongNameSignature();
367 PEImageLayoutHolder pLayout(GetLayout(PEImageLayout::LAYOUT_ANY,LAYOUT_CREATEIFNEEDED));
368 return pLayout->HasStrongNameSignature();
372 #ifndef DACCESS_COMPILE
375 #endif // !DACCESS_COMPILE
377 inline BOOL PEImage::IsIbcOptimized()
379 #ifdef FEATURE_PREJIT
381 if (HasLoadedLayout())
382 return GetLoadedLayout()->GetNativeILIsIbcOptimized();
385 PEImageLayoutHolder pLayout(GetLayout(PEImageLayout::LAYOUT_ANY,LAYOUT_CREATEIFNEEDED));
386 return pLayout->GetNativeILIsIbcOptimized();
393 #ifdef FEATURE_PREJIT
394 inline PTR_CVOID PEImage::GetNativeManifestMetadata(COUNT_T *pSize)
397 if (HasLoadedLayout())
398 return GetLoadedLayout()->GetNativeManifestMetadata(pSize);
401 PEImageLayoutHolder pLayout(GetLayout(PEImageLayout::LAYOUT_ANY,LAYOUT_CREATEIFNEEDED));
402 return pLayout->GetNativeManifestMetadata(pSize);
407 inline PTR_CVOID PEImage::GetMetadata(COUNT_T *pSize)
410 if (HasLoadedLayout())
411 return GetLoadedLayout()->GetMetadata(pSize);
414 PEImageLayoutHolder pLayout(GetLayout(PEImageLayout::LAYOUT_ANY,LAYOUT_CREATEIFNEEDED));
415 return pLayout->GetMetadata(pSize);
419 inline BOOL PEImage::HasNativeHeader()
422 if (HasLoadedLayout())
423 return GetLoadedLayout()->HasNativeHeader();
426 PEImageLayoutHolder pLayout(GetLayout(PEImageLayout::LAYOUT_ANY,LAYOUT_CREATEIFNEEDED));
427 return pLayout->HasNativeHeader();
431 inline BOOL PEImage::HasContents()
434 if (HasLoadedLayout())
435 return GetLoadedLayout()->HasContents();
438 PEImageLayoutHolder pLayout(GetLayout(PEImageLayout::LAYOUT_ANY,LAYOUT_CREATEIFNEEDED));
439 return pLayout->HasContents();
444 inline CHECK PEImage::CheckFormat()
447 if (HasLoadedLayout())
448 CHECK(GetLoadedLayout()->CheckFormat());
451 PEImageLayoutHolder pLayout(GetLayout(PEImageLayout::LAYOUT_ANY,LAYOUT_CREATEIFNEEDED));
452 CHECK(pLayout->CheckFormat());
456 inline PTR_CVOID PEImage::GetStrongNameSignature(COUNT_T *pSize)
459 if (HasLoadedLayout())
460 return GetLoadedLayout()->GetStrongNameSignature(pSize);
463 PEImageLayoutHolder pLayout(GetLayout(PEImageLayout::LAYOUT_ANY,LAYOUT_CREATEIFNEEDED));
464 return pLayout->GetStrongNameSignature(pSize);
468 inline void PEImage::Init(LPCWSTR pPath)
479 SetModuleFileNameHintForDAC();
481 #ifndef DACCESS_COMPILE
485 inline PTR_PEImage PEImage::FindByPath(LPCWSTR pPath)
492 PRECONDITION(s_hashLock.OwnedByCurrentThread());
496 int CaseHashHelper(const WCHAR *buffer, COUNT_T count, LocaleID lcid);
498 PEImageLocator locator(pPath);
499 #ifdef FEATURE_CASE_SENSITIVE_FILESYSTEM
500 DWORD dwHash=path.Hash();
502 DWORD dwHash = CaseHashHelper(pPath, (COUNT_T) wcslen(pPath), PEImage::GetFileSystemLocale());
504 return (PEImage *) s_Images->LookupValue(dwHash, &locator);
509 inline PTR_PEImage PEImage::OpenImage(LPCWSTR pPath, MDInternalImportFlags flags /* = MDInternalImport_Default */)
511 BOOL fUseCache = !((flags & MDInternalImport_NoCache) == MDInternalImport_NoCache);
515 PEImageHolder pImage(new PEImage);
517 return dac_cast<PTR_PEImage>(pImage.Extract());
520 CrstHolder holder(&s_hashLock);
522 PEImage* found = FindByPath(pPath);
525 if (found == (PEImage*) INVALIDENTRY)
527 // We did not find the entry in the Cache, and we've been asked to only use the cache.
528 if ((flags & MDInternalImport_OnlyLookInCache) == MDInternalImport_OnlyLookInCache)
533 PEImageHolder pImage(new PEImage);
534 #ifdef FEATURE_PREJIT
535 if (flags & MDInternalImport_TrustedNativeImage)
536 pImage->SetIsTrustedNativeImage();
537 if (flags & MDInternalImport_NativeImageInstall)
538 pImage->SetIsNativeImageInstall();
542 pImage->AddToHashMap();
543 return dac_cast<PTR_PEImage>(pImage.Extract());
548 return dac_cast<PTR_PEImage>(found);
552 inline BOOL PEImage::IsFileLocked()
555 return (m_pLayouts[IMAGE_FLAT])!=NULL || (m_pLayouts[IMAGE_MAPPED])!=NULL ;
558 #ifndef DACCESS_COMPILE
561 inline void PEImage::AddToHashMap()
571 _ASSERTE(s_hashLock.OwnedByCurrentThread());
572 s_Images->InsertValue(GetIDHash(),this);
581 inline BOOL PEImage::Has32BitNTHeaders()
584 if (HasLoadedLayout())
585 return GetLoadedLayout()->Has32BitNTHeaders();
588 PEImageLayoutHolder pLayout(GetLayout(PEImageLayout::LAYOUT_ANY,LAYOUT_CREATEIFNEEDED));
589 return pLayout->Has32BitNTHeaders();
593 inline BOOL PEImage::HasID()
595 LIMITED_METHOD_CONTRACT;
598 return !GetPath().IsEmpty();
601 inline ULONG PEImage::GetIDHash()
605 PRECONDITION(HasID());
613 #ifdef FEATURE_CASE_SENSITIVE_FILESYSTEM
614 RETURN m_path.Hash();
616 RETURN m_path.HashCaseInsensitive(PEImage::GetFileSystemLocale());
620 inline void PEImage::CachePEKindAndMachine()
630 // Do nothing if we have cached the information already
631 if(m_fCachedKindAndMachine)
634 PEImageLayoutHolder pLayout;
635 if (HasLoadedLayout())
637 pLayout.Assign(GetLoadedLayout(), false);
641 pLayout.Assign(GetLayout(PEImageLayout::LAYOUT_MAPPED|PEImageLayout::LAYOUT_FLAT,
642 PEImage::LAYOUT_CREATEIFNEEDED));
645 // Compute result into a local variables first
646 DWORD dwPEKind, dwMachine;
647 pLayout->GetPEKindAndMachine(&dwPEKind, &dwMachine);
649 // Write the final result into the lock-free cache.
650 m_dwPEKind = dwPEKind;
651 m_dwMachine = dwMachine;
653 m_fCachedKindAndMachine = TRUE;
656 inline void PEImage::GetPEKindAndMachine(DWORD* pdwKind, DWORD* pdwMachine)
659 CachePEKindAndMachine();
661 *pdwKind = m_dwPEKind;
663 *pdwMachine = m_dwMachine;
668 #ifndef DACCESS_COMPILE
669 inline void PEImage::AllocateLazyCOWPages()
671 STANDARD_VM_CONTRACT;
673 #ifdef FEATURE_LAZY_COW_PAGES
674 if (!m_bAllocatedLazyCOWPages && CLRConfig::GetConfigValue(CLRConfig::INTERNAL_ZapLazyCOWPagesEnabled))
676 ::AllocateLazyCOWPages(GetLoadedLayout());
677 m_bAllocatedLazyCOWPages = TRUE;
683 #endif // PEIMAGE_INL_