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 // --------------------------------------------------------------------------------
16 // --------------------------------------------------------------------------------
19 #include "peimagelayout.h"
24 // --------------------------------------------------------------------------------
25 // Forward declarations
26 // --------------------------------------------------------------------------------
31 Thread* GetThreadNULLOk();
33 // --------------------------------------------------------------------------------
34 // PEImage is a PE file loaded by our "simulated LoadLibrary" mechanism. A PEImage
35 // can be loaded either FLAT (same layout as on disk) or MAPPED (PE sections
36 // mapped into virtual addresses.)
38 // The MAPPED format is currently limited to "IL only" images - this can be checked
39 // for via PEDecoder::IsILOnlyImage.
41 // NOTE: PEImage will NEVER call LoadLibrary.
42 // --------------------------------------------------------------------------------
46 #define CV_SIGNATURE_RSDS 0x53445352
48 // CodeView RSDS debug information -> PDB 7.00
52 GUID signature; // unique identifier
53 DWORD age; // an always-incrementing value
54 char path[MAX_LONGPATH]; // zero terminated string with the name of the PDB file
57 typedef DPTR(class PEImage) PTR_PEImage;
61 friend class PEModule;
63 // ------------------------------------------------------------
65 // ------------------------------------------------------------
69 LAYOUT_CREATEIFNEEDED=1
71 PTR_PEImageLayout GetLayout(DWORD imageLayoutMask,DWORD flags); //with ref
72 PTR_PEImageLayout GetLoadedLayout(); //no ref
74 BOOL HasLoadedLayout();
77 // ------------------------------------------------------------
79 // ------------------------------------------------------------
81 static void Startup();
83 // Normal constructed PEImages do NOT share images between calls and
84 // cannot be accessed by Get methods.
86 // DO NOT USE these unless you want a private copy-on-write mapping of
95 #ifndef DACCESS_COMPILE
96 static PTR_PEImage LoadFlat(
100 static PTR_PEImage LoadImage(
102 #endif // !FEATURE_PAL
103 static PTR_PEImage OpenImage(
105 MDInternalImportFlags flags = MDInternalImport_Default);
108 // clones the image with new flags (this is pretty much about cached / noncached difference)
109 void Clone(MDInternalImportFlags flags, PTR_PEImage* ppImage)
111 if (GetPath().IsEmpty())
117 *ppImage = PEImage::OpenImage(GetPath(), flags);
121 // pUnkResource must be one of the ICLRPrivResource* interfaces defined in CLRPrivBinding.IDL.
122 // pUnkResource will be queried for each of these to find a match and
123 static PEImage * OpenImage(
124 ICLRPrivResource * pIResource,
125 MDInternalImportFlags flags = MDInternalImport_Default);
127 static PTR_PEImage FindById(UINT64 uStreamAsmId, DWORD dwModuleId);
128 static PTR_PEImage FindByPath(LPCWSTR pPath);
129 static PTR_PEImage FindByShortPath(LPCWSTR pPath);
130 static PTR_PEImage FindByLongPath(LPCWSTR pPath);
134 void SetLoadedHMODULE(HMODULE hMod);
135 void LoadNoMetaData();
137 void LoadFromMapped();
139 void AllocateLazyCOWPages();
145 PTR_CVOID GetStrongNameSignature(COUNT_T *pSize = NULL);
148 // Refcount above images.
153 const SString &GetPath();
155 HANDLE GetFileHandle();
156 void SetFileHandle(HANDLE hFile);
157 HRESULT TryOpenFile();
159 LPCWSTR GetPathForErrorMessages();
162 BOOL Equals(PEImage *pImage);
164 void GetMVID(GUID *pMvid);
165 const BOOL HasV1Metadata();
166 IMDInternalImport* GetMDImport();
167 BOOL MDImportLoaded();
168 IMDInternalImport* GetNativeMDImport(BOOL loadAllowed = TRUE);
171 BOOL HasNativeHeader() ;
172 BOOL IsPtrInImage(PTR_CVOID data);
176 CHECK CheckILFormat();
177 #ifdef FEATURE_PREJIT
178 CHECK CheckNativeFormat();
179 #endif // FEATURE_PREJIT
180 static CHECK CheckCanonicalFullPath(const SString &path);
181 static CHECK CheckStartup();
182 PTR_CVOID GetMetadata(COUNT_T *pSize = NULL);
183 void GetHashedStrongNameSignature(SBuffer &result);
186 static void GetPathFromDll(HINSTANCE hMod, SString &result);
187 #endif // !FEATURE_PAL
188 static LocaleID GetFileSystemLocale();
189 static BOOL PathEquals(const SString &p1, const SString &p2);
190 BOOL IsTrustedNativeImage(){LIMITED_METHOD_CONTRACT; return m_bIsTrustedNativeImage;};
191 void SetIsTrustedNativeImage(){LIMITED_METHOD_CONTRACT; m_bIsTrustedNativeImage=TRUE;};
192 BOOL IsNativeImageInstall(){LIMITED_METHOD_CONTRACT; return m_bIsNativeImageInstall;}
193 void SetIsNativeImageInstall(){LIMITED_METHOD_CONTRACT; m_bIsNativeImageInstall=TRUE;};
195 void SetModuleFileNameHintForDAC();
196 #ifdef DACCESS_COMPILE
197 void EnumMemoryRegions(CLRDataEnumMemoryFlags flags);
198 const SString &GetModuleFileNameHintForDAC();
201 const BOOL HasNTHeaders();
202 const BOOL HasCorHeader();
203 const BOOL HasReadyToRunHeader();
204 void SetPassiveDomainOnly();
205 BOOL PassiveDomainOnly();
206 BOOL IsReferenceAssembly();
207 #ifdef FEATURE_PREJIT
208 const BOOL IsNativeILILOnly();
209 const BOOL IsNativeILDll();
210 void GetNativeILPEKindAndMachine(DWORD* pdwKind, DWORD* pdwMachine);
211 PTR_CVOID GetNativeManifestMetadata(COUNT_T *pSize = NULL);
213 const BOOL HasDirectoryEntry(int entry);
214 const mdToken GetEntryPointToken();
215 const DWORD GetCorHeaderFlags();
216 const BOOL IsILOnly();
218 const WORD GetSubsystem();
220 const BOOL HasStrongNameSignature();
222 BOOL IsIbcOptimized();
223 BOOL Has32BitNTHeaders();
225 void VerifyIsAssembly();
226 void VerifyIsNIAssembly();
229 static void GetAll(SArray<PEImage*> &images);
232 #ifndef DACCESS_COMPILE
233 // Get or create the layout corresponding to the mask, with an AddRef
234 PTR_PEImageLayout GetLayoutInternal(DWORD imageLayoutMask, DWORD flags);
236 // Create the mapped layout
237 PTR_PEImageLayout CreateLayoutMapped();
239 // Create the flat layout
240 PTR_PEImageLayout CreateLayoutFlat(BOOL bPermitWriteableSections);
242 // Get an existing layout corresponding to the mask, no AddRef
243 PTR_PEImageLayout GetExistingLayoutInternal(DWORD imageLayoutMask);
246 void OpenNativeMDImport();
247 // ------------------------------------------------------------
249 // ------------------------------------------------------------
251 void Init(LPCWSTR pPath);
252 void Init(IStream* pStream, UINT64 uStreamAsmId,
253 DWORD dwModuleId, BOOL resourceFile);
255 void VerifyIsILOrNIAssembly(BOOL fIL);
257 struct PEImageLocator
262 PEImageLocator(LPCWSTR pPath)
267 PEImageLocator(PEImage * pImage)
268 : m_pPath(pImage->m_path.GetUnicode())
273 static BOOL CompareImage(UPTR image1, UPTR image2);
274 static BOOL CompareIJWDataBase(UPTR base, UPTR mapping);
276 void DECLSPEC_NORETURN ThrowFormat(HRESULT hr);
278 static CHECK CheckLayoutFormat(PEDecoder *pe);
280 // ------------------------------------------------------------
282 // ------------------------------------------------------------
287 // This variable will have the data of module name.
288 // It is only used by DAC to remap fusion loaded modules back to
289 // disk IL. This really is a workaround. The real fix is for fusion loader
290 // hook (public API on hosting) to take an additional file name hint.
291 // We are piggy backing on the fact that module name is the same as file name!!!
293 SString m_sModuleFileNameHintUsedByDac; // This is only used by DAC
295 BOOL m_bIsTrustedNativeImage;
296 BOOL m_bIsNativeImageInstall;
297 BOOL m_bPassiveDomainOnly;
298 #ifdef FEATURE_LAZY_COW_PAGES
299 BOOL m_bAllocatedLazyCOWPages;
300 #endif // FEATURE_LAZY_COW_PAGES
312 SimpleRWLock *m_pLayoutLock;
313 PTR_PEImageLayout m_pLayouts[IMAGE_COUNT] ;
315 #ifndef DACCESS_COMPILE
316 void SetLayout(DWORD dwLayout, PTR_PEImageLayout pLayout);
317 #endif // DACCESS_COMPILE
320 #ifdef METADATATRACKER_DATA
321 class MetaDataTracker *m_pMDTracker;
322 #endif // METADATATRACKER_DATA
324 IMDInternalImport* m_pMDImport;
325 IMDInternalImport* m_pNativeMDImport;
331 // ------------------------------------------------------------
333 // ------------------------------------------------------------
335 static CrstStatic s_hashLock;
337 static PtrHashMap *s_Images;
342 BOOL m_bSignatureInfoCached;
343 HRESULT m_hrSignatureInfoStatus;
344 DWORD m_dwSignatureInfo;
346 //@TODO:workaround: Remove this when we have one PEImage per mapped image,
347 //@TODO:workaround: and move the lock there
348 // This is for IJW thunk initialization, as it is no longer guaranteed
349 // that the initialization will occur under the loader lock.
350 static CrstStatic s_ijwHashLock;
351 static PtrHashMap *s_ijwFixupDataHash;
360 PTR_LoaderHeap m_DllThunkHeap;
362 // the fixup for the next iteration in FixupVTables
363 // we use it to make sure that we do not try to fix up the same entry twice
364 // if there was a pass that was aborted in the middle
365 COUNT_T m_iNextFixup;
366 COUNT_T m_iNextMethod;
373 IJWFixupData(void *pBase);
375 void *GetBase() { LIMITED_METHOD_CONTRACT; return m_base; }
376 Crst *GetLock() { LIMITED_METHOD_CONTRACT; return &m_lock; }
377 BOOL IsFixedUp() { LIMITED_METHOD_CONTRACT; return m_flags & e_FIXED_UP; }
378 void SetIsFixedUp() { LIMITED_METHOD_CONTRACT; m_flags |= e_FIXED_UP; }
379 PTR_LoaderHeap GetThunkHeap();
380 void MarkMethodFixedUp(COUNT_T iFixup, COUNT_T iMethod);
381 BOOL IsMethodFixedUp(COUNT_T iFixup, COUNT_T iMethod);
384 static IJWFixupData *GetIJWData(void *pBase);
385 static PTR_LoaderHeap GetDllThunkHeap(void *pBase);
386 static void UnloadIJWModule(void *pBase);
391 BOOL m_fCachedKindAndMachine;
396 void CachePEKindAndMachine();
397 void GetPEKindAndMachine(DWORD* pdwKind, DWORD* pdwMachine);
401 FORCEINLINE void PEImageRelease(PEImage *i)
407 typedef Wrapper<PEImage *, DoNothing, PEImageRelease> PEImageHolder;
409 // ================================================================================
410 // Inline definitions
411 // ================================================================================
413 #include "peimage.inl"