Remove always defined FEATURE_CORECLR
[platform/upstream/coreclr.git] / src / vm / pefile.inl
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 // --------------------------------------------------------------------------------
5 // PEFile.inl
6 // 
7
8 // --------------------------------------------------------------------------------
9
10 #ifndef PEFILE_INL_
11 #define PEFILE_INL_
12
13 #include "strongname.h"
14 #include "strongnameholders.h"
15 #ifdef FEATURE_FUSION
16 #include "fusionbind.h"
17 #endif
18 #include "check.h"
19 #include "simplerwlock.hpp"
20 #include "eventtrace.h"
21 #include "peimagelayout.inl"
22
23 #if CHECK_INVARIANTS
24 inline CHECK PEFile::Invariant()
25 {
26     CONTRACT_CHECK
27     {
28         INSTANCE_CHECK;
29         THROWS;
30         GC_TRIGGERS;
31         MODE_ANY;
32     }
33     CONTRACT_CHECK_END;
34
35     if (IsDynamic())
36     {
37         // dynamic module case
38         CHECK(m_openedILimage == NULL);
39 #ifdef FEATURE_PREJIT
40         CHECK(m_nativeImage == NULL);
41 #endif
42         CHECK(CheckPointer(m_pEmitter));
43     }
44     else
45     {
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));
49 #ifdef FEATURE_PREJIT
50         CHECK(CheckPointer((PEImage*) m_nativeImage, NULL_OK));
51 #endif
52     }
53     CHECK_OK;
54 }
55 #endif // CHECK_INVARIANTS
56
57 // ------------------------------------------------------------
58 // AddRef/Release
59 // ------------------------------------------------------------
60
61 inline ULONG PEFile::AddRef()
62 {
63     CONTRACTL
64     {
65         PRECONDITION(m_refCount < COUNT_T_MAX);
66         NOTHROW;
67         GC_NOTRIGGER;
68         CANNOT_TAKE_LOCK;
69         MODE_ANY;
70     }
71     CONTRACTL_END;
72
73     return FastInterlockIncrement(&m_refCount);
74 }
75
76 inline ULONG PEFile::Release()
77 {
78     CONTRACT(COUNT_T)
79     {
80         DESTRUCTOR_CHECK;
81         NOTHROW;
82         GC_TRIGGERS;
83         MODE_ANY;
84     }
85     CONTRACT_END;
86     
87     LONG result = FastInterlockDecrement(&m_refCount);
88     _ASSERTE(result >= 0);
89     if (result == 0)
90         delete this;
91     
92     RETURN result;
93 }
94
95 // ------------------------------------------------------------
96 // Identity
97 // ------------------------------------------------------------
98
99 inline ULONG PEAssembly::HashIdentity()
100 {
101     CONTRACTL
102     {
103         PRECONDITION(CheckPointer(m_identity));
104         MODE_ANY;
105         THROWS;
106         GC_TRIGGERS;
107     }
108     CONTRACTL_END;
109 #ifdef FEATURE_VERSIONING
110     return BINDER_SPACE::GetAssemblyFromPrivAssemblyFast(m_pHostAssembly)->GetAssemblyName()->Hash(BINDER_SPACE::AssemblyName::INCLUDE_VERSION);
111 #else
112     if (!m_identity->HasID())
113     {
114         if (!IsLoaded())
115             return 0;
116         else
117             return (ULONG) dac_cast<TADDR>(GetLoaded()->GetBase());
118     }
119     else
120         return m_identity->GetIDHash();
121 #endif
122 }
123
124 inline void PEFile::ValidateForExecution()
125 {
126     CONTRACTL
127     {
128         MODE_ANY;
129         THROWS;
130         GC_TRIGGERS;
131     }
132     CONTRACTL_END;
133
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())
137         return;
138
139     //
140     // Ensure reference assemblies are not loaded for execution
141     //
142     ReleaseHolder<IMDInternalImport> mdImport(this->GetMDImportWithRef());
143     if (mdImport->GetCustomAttributeByName(TokenFromRid(1, mdtAssembly),
144                                            g_ReferenceAssemblyAttribute,
145                                            NULL,
146                                            NULL) == S_OK) {
147         ThrowHR(COR_E_LOADING_REFERENCE_ASSEMBLY, BFA_REFERENCE_ASSEMBLY);
148     }
149
150     //
151     // Ensure platform is valid for execution
152     //
153     if (!IsDynamic() && !IsResource()) 
154     {
155         if (IsMarkedAsNoPlatform())
156         {
157             if (IsMarkedAsContentTypeWindowsRuntime())
158             {
159                 ThrowHR(COR_E_LOADING_WINMD_REFERENCE_ASSEMBLY);
160             }
161             else
162             {
163                 ThrowHR(COR_E_BADIMAGEFORMAT);
164             }
165         }
166     }
167 }
168
169
170 inline BOOL PEFile::IsMarkedAsNoPlatform()
171 {
172     WRAPPER_NO_CONTRACT;
173     return (IsAfPA_NoPlatform(GetFlags()));
174 }
175
176 inline BOOL PEFile::IsMarkedAsContentTypeWindowsRuntime()
177 {
178     WRAPPER_NO_CONTRACT;
179     return (IsAfContentType_WindowsRuntime(GetFlags()));
180 }
181
182
183 inline void PEFile::GetMVID(GUID *pMvid)
184 {
185     CONTRACTL
186     {
187         THROWS;
188         GC_NOTRIGGER;
189         FORBID_FAULT;
190         MODE_ANY;
191     }
192     CONTRACTL_END;
193     
194     IfFailThrow(GetPersistentMDImport()->GetScopeProps(NULL, pMvid));
195 }
196
197 inline BOOL PEFile::PassiveDomainOnly()
198 {
199     WRAPPER_NO_CONTRACT;
200     return HasOpenedILimage() && GetOpenedILimage()->PassiveDomainOnly();
201 }
202
203 // ------------------------------------------------------------
204 // Loader support routines
205 // ------------------------------------------------------------
206
207 inline void PEFile::SetSkipVerification()
208 {
209     LIMITED_METHOD_CONTRACT;
210
211     m_flags |= PEFILE_SKIP_VERIFICATION; 
212 }
213
214 inline BOOL PEFile::HasSkipVerification()
215 {
216     LIMITED_METHOD_CONTRACT;
217
218     return (m_flags & (PEFILE_SKIP_VERIFICATION | PEFILE_SYSTEM)) != 0; 
219 }
220
221 // ------------------------------------------------------------
222 // Descriptive strings
223 // ------------------------------------------------------------
224
225 inline const SString &PEFile::GetPath()
226 {
227     CONTRACTL
228     {
229         INSTANCE_CHECK;
230         GC_NOTRIGGER;
231         NOTHROW;
232         CANNOT_TAKE_LOCK;
233         MODE_ANY;
234         SO_TOLERANT;
235         SUPPORTS_DAC;
236     }
237     CONTRACTL_END;
238
239     if (IsDynamic())
240     {
241         return SString::Empty();
242     }
243     else
244         return m_identity->GetPath();
245 }
246
247
248 #ifdef DACCESS_COMPILE
249 inline const SString &PEFile::GetModuleFileNameHint()
250 {
251     CONTRACTL
252     {
253         INSTANCE_CHECK;
254         GC_NOTRIGGER;
255         NOTHROW;
256         MODE_ANY;
257     }
258     CONTRACTL_END;
259
260     if (IsDynamic())
261     {
262         return SString::Empty();
263     }
264     else
265         return m_identity->GetModuleFileNameHintForDAC();
266 }
267 #endif // DACCESS_COMPILE
268
269 #ifdef LOGGING
270 inline LPCWSTR PEFile::GetDebugName()
271 {
272     CONTRACTL
273     {
274         INSTANCE_CHECK;
275         NOTHROW;
276         GC_NOTRIGGER;
277         MODE_ANY;
278         CANNOT_TAKE_LOCK;
279     }
280     CONTRACTL_END;
281     
282 #ifdef _DEBUG
283     return m_pDebugName;
284 #else
285     return GetPath();
286 #endif
287 }
288 #endif
289
290 // ------------------------------------------------------------
291 // Classification
292 // ------------------------------------------------------------
293
294 inline BOOL PEFile::IsAssembly() const
295 {
296     LIMITED_METHOD_DAC_CONTRACT;
297
298     return (m_flags & PEFILE_ASSEMBLY) != 0;
299 }
300
301 inline PTR_PEAssembly PEFile::AsAssembly()
302 {
303     LIMITED_METHOD_DAC_CONTRACT;
304
305     if (this == nullptr)
306         return dac_cast<PTR_PEAssembly>(nullptr);
307     if (IsAssembly())
308         return dac_cast<PTR_PEAssembly>(this);
309     else
310         return dac_cast<PTR_PEAssembly>(nullptr);
311 }
312
313 inline BOOL PEFile::IsModule() const
314 {
315     LIMITED_METHOD_CONTRACT;
316     SUPPORTS_DAC;
317
318     return (m_flags & PEFILE_MODULE) != 0;
319 }
320
321 inline PTR_PEModule PEFile::AsModule()
322 {
323     LIMITED_METHOD_DAC_CONTRACT;
324
325     if (this == nullptr)
326         return dac_cast<PTR_PEModule>(nullptr);
327     if (IsModule())
328         return dac_cast<PTR_PEModule>(this);
329     else
330         return dac_cast<PTR_PEModule>(nullptr);
331 }
332
333 inline BOOL PEFile::IsSystem() const
334 {
335     LIMITED_METHOD_CONTRACT;
336     SUPPORTS_DAC;
337
338     return (m_flags & PEFILE_SYSTEM) != 0;
339 }
340
341 inline BOOL PEFile::IsDynamic() const
342 {
343     LIMITED_METHOD_CONTRACT;
344     SUPPORTS_DAC;
345
346     return m_identity == NULL;
347 }
348
349 inline BOOL PEFile::IsResource() const
350 {
351     WRAPPER_NO_CONTRACT;
352     SUPPORTS_DAC;
353
354 #ifdef FEATURE_MULTIMODULE_ASSEMBLIES
355     return IsModule() && dac_cast<PTR_PEModule>(this)->IsResource();
356 #else
357     return FALSE;
358 #endif // FEATURE_MULTIMODULE_ASSEMBLIES
359 }
360
361 inline BOOL PEFile::IsIStream() const
362 {
363     LIMITED_METHOD_CONTRACT;
364
365     return (m_flags & PEFILE_ISTREAM) != 0;
366 }
367
368 inline BOOL PEFile::IsIntrospectionOnly() const
369 {
370     WRAPPER_NO_CONTRACT;
371     STATIC_CONTRACT_SO_TOLERANT;
372 #ifdef FEATURE_MULTIMODULE_ASSEMBLIES
373     if (IsModule())
374     {
375         return dac_cast<PTR_PEModule>(this)->GetAssembly()->IsIntrospectionOnly();
376     }
377     else
378 #endif //  FEATURE_MULTIMODULE_ASSEMBLIES
379     {
380         return (m_flags & PEFILE_INTROSPECTIONONLY) != 0;
381     }
382 }
383
384
385 inline PEAssembly *PEFile::GetAssembly() const
386 {
387     WRAPPER_NO_CONTRACT;
388 #ifdef FEATURE_MULTIMODULE_ASSEMBLIES
389     if (IsAssembly())
390         return dac_cast<PTR_PEAssembly>(this);
391     else
392         return dac_cast<PTR_PEModule>(this)->GetAssembly();
393 #else
394     _ASSERTE(IsAssembly());
395     return dac_cast<PTR_PEAssembly>(this);
396
397 #endif // FEATURE_MULTIMODULE_ASSEMBLIES
398 }
399
400 // ------------------------------------------------------------
401 // Hash support
402 // ------------------------------------------------------------
403
404 #ifndef DACCESS_COMPILE
405 inline void PEFile::GetImageBits(SBuffer &result)
406 {
407     CONTRACTL
408     {
409         INSTANCE_CHECK;
410         PRECONDITION(CheckValue(result));
411         THROWS;
412         GC_TRIGGERS;
413         MODE_ANY;
414     }
415     CONTRACTL_END;
416
417     EnsureImageOpened();
418     // We don't cache any other hashes right now.
419     if (!IsDynamic())
420         GetILimage()->GetImageBits(PEImageLayout::LAYOUT_FLAT,result);
421 }
422
423 inline void PEFile::GetHash(ALG_ID algorithm, SBuffer &result)
424 {
425     CONTRACTL
426     {
427         INSTANCE_CHECK;
428         PRECONDITION(CheckValue(result));
429         THROWS;
430         GC_TRIGGERS;
431         MODE_ANY;
432     }
433     CONTRACTL_END;
434
435     if (algorithm == CALG_SHA1)
436     {
437         GetSHA1Hash(result);
438     }
439     else
440     {
441         EnsureImageOpened();
442         // We don't cache any other hashes right now.
443         GetILimage()->ComputeHash(algorithm, result);
444     }
445 }
446     
447 inline CHECK PEFile::CheckHash(ALG_ID algorithm, const void *hash, COUNT_T size)
448 {
449     CONTRACT_CHECK
450     {
451         INSTANCE_CHECK;
452         PRECONDITION(CheckPointer(hash));
453         THROWS;
454         GC_TRIGGERS;
455         MODE_ANY;
456     }
457     CONTRACT_CHECK_END;
458
459     StackSBuffer hashBuffer;
460     GetHash(algorithm, hashBuffer);
461
462     CHECK(hashBuffer.Equals((const BYTE *)hash, size));
463
464     CHECK_OK;
465 }
466 #endif // DACCESS_COMPILE
467
468 // ------------------------------------------------------------
469 // Metadata access
470 // ------------------------------------------------------------
471
472 inline BOOL PEFile::HasMetadata()
473 {
474     CONTRACTL
475     {
476         INSTANCE_CHECK;
477         NOTHROW;
478         GC_NOTRIGGER;
479         MODE_ANY;
480         SUPPORTS_DAC;
481     }
482     CONTRACTL_END;
483
484     return !IsResource();
485 }
486
487 inline IMDInternalImportHolder PEFile::GetMDImport()
488 {
489     WRAPPER_NO_CONTRACT;
490     if (m_bHasPersistentMDImport)
491         return IMDInternalImportHolder(GetPersistentMDImport(),FALSE);
492     else
493         return IMDInternalImportHolder(GetMDImportWithRef(),TRUE);
494 };
495
496 inline IMDInternalImport* PEFile::GetPersistentMDImport()
497 {
498 /*
499     CONTRACT(IMDInternalImport *) 
500     {
501         INSTANCE_CHECK;
502         PRECONDITION(!IsResource());
503         POSTCONDITION(CheckPointer(RETVAL));
504         NOTHROW;
505         GC_NOTRIGGER;
506         MODE_ANY;
507     }
508     CONTRACT_END;
509 */
510     SUPPORTS_DAC;
511 #if !defined(__GNUC__)
512
513     _ASSERTE(!IsResource());
514 #endif
515 #ifdef DACCESS_COMPILE
516     WRAPPER_NO_CONTRACT;
517     return DacGetMDImport(this, true);
518 #else
519     LIMITED_METHOD_CONTRACT;
520
521     return m_pMDImport;
522 #endif
523 }
524
525 inline IMDInternalImport *PEFile::GetMDImportWithRef()
526 {
527 /*
528     CONTRACT(IMDInternalImport *) 
529     {
530         INSTANCE_CHECK;
531         PRECONDITION(!IsResource());
532         POSTCONDITION(CheckPointer(RETVAL));
533         NOTHROW;
534         GC_NOTRIGGER;
535         MODE_ANY;
536         SO_INTOLERANT;
537     }
538     CONTRACT_END;
539 */
540 #if !defined(__GNUC__)
541     _ASSERTE(!IsResource());
542 #endif
543 #ifdef DACCESS_COMPILE
544     WRAPPER_NO_CONTRACT;
545     return DacGetMDImport(this, true);
546 #else
547     CONTRACTL
548     {
549         NOTHROW;
550         WRAPPER(GC_TRIGGERS);
551         MODE_ANY;
552         CAN_TAKE_LOCK;
553         SO_INTOLERANT;
554     }
555     CONTRACTL_END;
556
557     GCX_PREEMP();
558     SimpleReadLockHolder lock(m_pMetadataLock);
559     if(m_pMDImport)
560         m_pMDImport->AddRef();
561     return m_pMDImport;
562 #endif
563 }
564
565 #ifndef DACCESS_COMPILE
566
567 inline IMetaDataImport2 *PEFile::GetRWImporter()
568 {
569     CONTRACT(IMetaDataImport2 *) 
570     {
571         INSTANCE_CHECK;
572         PRECONDITION(!IsResource());
573         POSTCONDITION(CheckPointer(RETVAL));
574         PRECONDITION(m_bHasPersistentMDImport);
575         GC_NOTRIGGER;
576         THROWS;
577         MODE_ANY;
578     }
579     CONTRACT_END;
580
581     if (m_pImporter == NULL)
582         OpenImporter();
583
584     RETURN m_pImporter;
585 }
586
587 inline IMetaDataEmit *PEFile::GetEmitter()
588 {
589     CONTRACT(IMetaDataEmit *) 
590     {
591         INSTANCE_CHECK;
592         MODE_ANY;
593         GC_NOTRIGGER;
594         PRECONDITION(!IsResource());
595         POSTCONDITION(CheckPointer(RETVAL));
596         PRECONDITION(m_bHasPersistentMDImport);
597         THROWS;
598     }
599     CONTRACT_END;
600
601     if (m_pEmitter == NULL)
602         OpenEmitter();
603
604     RETURN m_pEmitter;
605 }
606
607
608 #endif // DACCESS_COMPILE
609
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()
614 {
615     CONTRACT(LPCUTF8)
616     {
617         INSTANCE_CHECK;
618         MODE_ANY;
619         POSTCONDITION(CheckPointer(RETVAL));
620         NOTHROW;
621         SUPPORTS_DAC;
622         WRAPPER(GC_TRIGGERS);
623     }
624     CONTRACT_END;
625
626     if (IsAssembly())
627         RETURN dac_cast<PTR_PEAssembly>(this)->GetSimpleName();
628 #ifdef FEATURE_MULTIMODULE_ASSEMBLIES
629     else if (IsModule())
630         RETURN dac_cast<PTR_PEModule>(this)->GetSimpleName();
631 #endif // FEATURE_MULTIMODULE_ASSEMBLIES
632     else 
633     {
634         LPCUTF8 szScopeName;
635         if (FAILED(GetScopeName(&szScopeName)))
636         {
637             szScopeName = ""; 
638         }
639         RETURN szScopeName;
640     }
641 }
642
643
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)
648 {
649     CONTRACTL
650     {
651         INSTANCE_CHECK;
652         MODE_ANY;
653         NOTHROW;
654         SUPPORTS_DAC;
655         GC_NOTRIGGER;
656     }
657     CONTRACTL_END;
658
659     return GetMDImport()->GetScopeProps(pszName, NULL);
660 }
661
662
663 // ------------------------------------------------------------
664 // PE file access
665 // ------------------------------------------------------------
666
667 inline BOOL PEFile::HasSecurityDirectory()
668 {
669     WRAPPER_NO_CONTRACT;
670
671     if (IsResource() || IsDynamic())
672         return FALSE;
673
674 #ifdef FEATURE_PREJIT
675     if (IsNativeLoaded())
676     {
677         CONSISTENCY_CHECK(HasNativeImage());
678
679         return m_nativeImage->GetNativeILHasSecurityDirectory();
680     }
681 #ifndef DACCESS_COMPILE
682     if (!HasOpenedILimage())
683     {
684         //don't want to touch the IL image unless we already have
685         ReleaseHolder<PEImage> pNativeImage = GetNativeImageWithRef();
686         if (pNativeImage)
687             return pNativeImage->GetNativeILHasSecurityDirectory();
688     }
689 #endif // DACCESS_COMPILE
690 #endif // FEATURE_PREJIT
691
692     if (!GetILimage()->HasNTHeaders())
693         return FALSE;
694
695     return GetOpenedILimage()->HasDirectoryEntry(IMAGE_DIRECTORY_ENTRY_SECURITY);
696 }
697
698 inline BOOL PEFile::IsIbcOptimized()
699 {
700     WRAPPER_NO_CONTRACT;
701
702 #ifdef FEATURE_PREJIT
703     if (IsNativeLoaded())
704     {
705         CONSISTENCY_CHECK(HasNativeImage());
706
707         return m_nativeImage->IsIbcOptimized();
708     }
709 #endif
710
711     return FALSE;
712 }
713
714 inline BOOL PEFile::IsILImageReadyToRun()
715 {
716     CONTRACTL
717     {
718         INSTANCE_CHECK;
719         MODE_ANY;
720         NOTHROW;
721         GC_NOTRIGGER;
722     }
723     CONTRACTL_END;
724
725 #ifdef FEATURE_PREJIT
726     if (IsNativeLoaded())
727     {
728         CONSISTENCY_CHECK(HasNativeImage());
729
730         return GetLoadedNative()->GetNativeILHasReadyToRunHeader();
731     }
732     else
733 #endif // FEATURE_PREJIT
734     if (HasOpenedILimage())
735     {
736         return GetLoadedIL()->HasReadyToRunHeader();
737     }
738     else
739     {
740         return FALSE;
741     }
742 }
743
744 inline WORD PEFile::GetSubsystem()
745 {
746     WRAPPER_NO_CONTRACT;
747
748     if (IsResource() || IsDynamic())
749         return 0;
750
751 #ifdef FEATURE_PREJIT
752     if (IsNativeLoaded())
753     {
754         CONSISTENCY_CHECK(HasNativeImage());
755
756         return GetLoadedNative()->GetSubsystem();
757     }
758 #ifndef DACCESS_COMPILE
759     if (!HasOpenedILimage())
760     {
761         //don't want to touch the IL image unless we already have
762         ReleaseHolder<PEImage> pNativeImage = GetNativeImageWithRef();
763         if (pNativeImage)
764             return pNativeImage->GetSubsystem();
765     }
766 #endif // DACCESS_COMPILE
767 #endif // FEATURE_PREJIT
768  
769     return GetLoadedIL()->GetSubsystem();
770 }
771
772 inline mdToken PEFile::GetEntryPointToken(
773 #ifdef _DEBUG
774             BOOL bAssumeLoaded
775 #endif //_DEBUG
776             )
777 {
778     WRAPPER_NO_CONTRACT;
779
780     if (IsResource() || IsDynamic())
781         return mdTokenNil;
782
783
784 #ifdef FEATURE_PREJIT
785     if (IsNativeLoaded())
786     {
787         CONSISTENCY_CHECK(HasNativeImage());
788         _ASSERTE (!bAssumeLoaded || m_nativeImage->HasLoadedLayout ());
789         return m_nativeImage->GetEntryPointToken();
790     }
791 #ifndef DACCESS_COMPILE
792     if (!HasOpenedILimage())
793     {
794         //don't want to touch the IL image unless we already have
795         ReleaseHolder<PEImage> pNativeImage = GetNativeImageWithRef();
796         if (pNativeImage) {
797             _ASSERTE (!bAssumeLoaded || pNativeImage->HasLoadedLayout ());
798             return pNativeImage->GetEntryPointToken();
799         }
800     }
801 #endif // DACCESS_COMPILE
802 #endif // FEATURE_PREJIT
803     _ASSERTE (!bAssumeLoaded || HasLoadedIL ());
804     return GetOpenedILimage()->GetEntryPointToken();
805 }
806
807 #ifdef FEATURE_PREJIT
808 inline BOOL PEFile::IsNativeLoaded()
809 {
810     WRAPPER_NO_CONTRACT;
811     return (m_nativeImage && m_bHasPersistentMDImport && m_nativeImage->HasLoadedLayout());
812 }
813 inline void PEFile::MarkNativeImageInvalidIfOwned()
814 {
815     WRAPPER_NO_CONTRACT;
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());
820
821     // Attempt to write only if we claimed the ownership.
822     if (*ppNativeFile == this)
823         FastInterlockCompareExchangePointer(ppNativeFile, Dummy(), this);
824 }
825
826
827 #endif
828
829 inline BOOL PEFile::IsILOnly()
830 {
831     STATIC_CONTRACT_SO_TOLERANT;
832     WRAPPER_NO_CONTRACT;
833     SUPPORTS_DAC;
834
835     CONTRACT_VIOLATION(ThrowsViolation|GCViolation|FaultViolation);
836     
837     if (IsResource() || IsDynamic())
838         return FALSE;
839
840 #ifdef FEATURE_PREJIT
841     if (IsNativeLoaded())
842     {
843         CONSISTENCY_CHECK(HasNativeImage());
844
845         return m_nativeImage->IsNativeILILOnly();
846     }
847 #ifndef DACCESS_COMPILE
848     if (!HasOpenedILimage())
849     {
850         BOOL retVal = FALSE;
851
852         BEGIN_SO_INTOLERANT_CODE(GetThread());
853
854         //don't want to touch the IL image unless we already have
855         ReleaseHolder<PEImage> pNativeImage = GetNativeImageWithRef();
856         if (pNativeImage)
857         {
858             retVal = pNativeImage->IsNativeILILOnly();
859         }
860
861         END_SO_INTOLERANT_CODE;
862
863         return retVal;
864     }
865 #endif // DACCESS_COMPILE
866 #endif // FEATURE_PREJIT
867
868     return GetOpenedILimage()->IsILOnly();
869 }
870
871 inline BOOL PEFile::IsDll()
872 {
873     WRAPPER_NO_CONTRACT;
874
875     if (IsResource() || IsDynamic())
876         return TRUE;
877
878 #ifdef FEATURE_PREJIT
879     if (IsNativeLoaded())
880     {
881         CONSISTENCY_CHECK(HasNativeImage());
882
883         return m_nativeImage->IsNativeILDll();
884     }
885 #ifndef DACCESS_COMPILE
886     if (!HasOpenedILimage())
887     {
888         //don't want to touch the IL image unless we already have
889         ReleaseHolder<PEImage> pNativeImage =GetNativeImageWithRef();
890         if (pNativeImage)
891             return pNativeImage->IsNativeILDll();
892     }
893     EnsureImageOpened();
894 #endif // DACCESS_COMPILE
895 #endif // FEATURE_PREJIT
896
897     return GetOpenedILimage()->IsDll();
898 }
899
900 inline PTR_VOID PEFile::GetRvaField(RVA field)
901 {
902     CONTRACT(void *)
903     {
904         INSTANCE_CHECK;
905         PRECONDITION(!IsDynamic());
906         PRECONDITION(!IsResource());
907         PRECONDITION(CheckRvaField(field));
908         PRECONDITION(CheckLoaded());
909         NOTHROW;
910         GC_NOTRIGGER;
911         MODE_ANY;
912         SUPPORTS_DAC;
913         POSTCONDITION(CheckPointer(RETVAL));
914     }
915     CONTRACT_END;
916
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.
919     
920     RETURN dac_cast<PTR_VOID>(GetLoadedIL()->GetRvaData(field,NULL_OK));
921 }
922
923 inline CHECK PEFile::CheckRvaField(RVA field)
924 {
925     CONTRACT_CHECK
926     {
927         INSTANCE_CHECK;
928         PRECONDITION(!IsDynamic());
929         PRECONDITION(!IsResource());
930         PRECONDITION(CheckLoaded());
931         NOTHROW;
932         GC_NOTRIGGER;
933         MODE_ANY;
934     }
935     CONTRACT_CHECK_END;
936         
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.
939     
940     CHECK(GetLoadedIL()->CheckRva(field,NULL_OK));
941     CHECK_OK;
942 }
943
944 inline CHECK PEFile::CheckRvaField(RVA field, COUNT_T size)
945 {
946     CONTRACT_CHECK
947     {
948         INSTANCE_CHECK;
949         PRECONDITION(!IsDynamic());
950         PRECONDITION(!IsResource());
951         PRECONDITION(CheckLoaded());
952         NOTHROW;
953         GC_NOTRIGGER;
954         MODE_ANY;
955     }
956     CONTRACT_CHECK_END;
957
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.
960     
961     CHECK(GetLoadedIL()->CheckRva(field, size,0,NULL_OK));
962     CHECK_OK;
963 }
964
965 inline BOOL PEFile::HasTls()
966 {
967     CONTRACTL
968     {
969         INSTANCE_CHECK;
970         NOTHROW;
971         GC_NOTRIGGER;
972         MODE_ANY;
973         PRECONDITION(CheckLoaded());
974     }
975     CONTRACTL_END;
976
977     // Resource modules do not contain TLS data.
978     if (IsResource())
979         return FALSE;
980     // Dynamic modules do not contain TLS data.
981     else if (IsDynamic())
982         return FALSE;
983     // ILOnly modules do not contain TLS data.
984     else if (IsILOnly())
985         return FALSE;
986     else
987         return GetLoadedIL()->HasTls();
988 }
989
990 inline BOOL PEFile::IsRvaFieldTls(RVA field)
991 {
992     CONTRACTL
993     {
994         INSTANCE_CHECK;
995         NOTHROW;
996         GC_NOTRIGGER;
997         MODE_ANY;
998         PRECONDITION(CheckLoaded());
999     }
1000     CONTRACTL_END;
1001
1002     if (!HasTls())
1003         return FALSE;
1004
1005     PTR_VOID address = PTR_VOID(GetLoadedIL()->GetRvaData(field));
1006
1007     COUNT_T tlsSize;
1008     PTR_VOID tlsRange = GetLoadedIL()->GetTlsRange(&tlsSize);
1009
1010     return (address >= tlsRange
1011             && address < (dac_cast<PTR_BYTE>(tlsRange)+tlsSize));
1012 }
1013
1014 inline UINT32 PEFile::GetFieldTlsOffset(RVA field)
1015 {
1016     CONTRACTL
1017     {
1018         INSTANCE_CHECK;
1019         PRECONDITION(CheckRvaField(field));
1020         PRECONDITION(IsRvaFieldTls(field));
1021         PRECONDITION(CheckLoaded());
1022         NOTHROW;
1023         GC_NOTRIGGER;
1024         MODE_ANY;
1025     }
1026     CONTRACTL_END;
1027         
1028     return (UINT32)(dac_cast<PTR_BYTE>(GetRvaField(field)) - 
1029                                 dac_cast<PTR_BYTE>(GetLoadedIL()->GetTlsRange()));
1030 }
1031         
1032 inline UINT32 PEFile::GetTlsIndex()
1033 {
1034     CONTRACTL
1035     {
1036         PRECONDITION(CheckLoaded());
1037         INSTANCE_CHECK;
1038         PRECONDITION(HasTls());
1039         NOTHROW;
1040         GC_NOTRIGGER;
1041         MODE_ANY;
1042     }
1043     CONTRACTL_END;
1044
1045     return GetLoadedIL()->GetTlsIndex();
1046 }
1047
1048 inline const void *PEFile::GetInternalPInvokeTarget(RVA target)
1049 {
1050     CONTRACT(void *)
1051     {
1052         INSTANCE_CHECK;
1053         PRECONDITION(!IsDynamic());
1054         PRECONDITION(!IsResource());
1055         PRECONDITION(CheckInternalPInvokeTarget(target));
1056         PRECONDITION(CheckLoaded());
1057         NOTHROW;
1058         GC_NOTRIGGER;
1059         MODE_ANY;
1060         POSTCONDITION(CheckPointer(RETVAL));
1061     }
1062     CONTRACT_END;
1063
1064     RETURN (void*)GetLoadedIL()->GetRvaData(target);
1065 }
1066
1067 inline CHECK PEFile::CheckInternalPInvokeTarget(RVA target)
1068 {
1069     CONTRACT_CHECK
1070     {
1071         INSTANCE_CHECK;
1072         PRECONDITION(!IsDynamic());
1073         PRECONDITION(!IsResource());
1074         PRECONDITION(CheckLoaded());
1075         NOTHROW;
1076         GC_NOTRIGGER;
1077         MODE_ANY;
1078     }
1079     CONTRACT_CHECK_END;
1080
1081     CHECK(!IsILOnly());
1082     CHECK(GetLoadedIL()->CheckRva(target));
1083     
1084     CHECK_OK;
1085 }
1086     
1087 inline PCCOR_SIGNATURE  PEFile::GetSignature(RVA signature)
1088 {
1089     CONTRACT(PCCOR_SIGNATURE)
1090     {
1091         INSTANCE_CHECK;
1092         PRECONDITION(!IsDynamic() || signature == 0);
1093         PRECONDITION(!IsResource());
1094         PRECONDITION(CheckSignatureRva(signature));
1095         POSTCONDITION(CheckSignature(RETVAL));
1096         PRECONDITION(CheckLoaded());
1097         NOTHROW;
1098         GC_NOTRIGGER;
1099         MODE_ANY;
1100     }
1101     CONTRACT_END;
1102
1103     if (signature == 0)
1104         RETURN NULL;
1105     else
1106         RETURN (PCCOR_SIGNATURE) GetLoadedIL()->GetRvaData(signature);
1107 }
1108
1109 inline RVA PEFile::GetSignatureRva(PCCOR_SIGNATURE signature)
1110 {
1111     CONTRACT(RVA)
1112     {
1113         INSTANCE_CHECK;
1114         PRECONDITION(!IsDynamic() || signature == NULL);
1115         PRECONDITION(!IsResource());
1116         PRECONDITION(CheckSignature(signature));
1117         POSTCONDITION(CheckSignatureRva(RETVAL));
1118         PRECONDITION(CheckLoaded());
1119         NOTHROW;
1120         GC_NOTRIGGER;
1121         MODE_ANY;
1122     }
1123     CONTRACT_END;
1124
1125     if (signature == NULL)
1126         RETURN 0;
1127     else
1128         RETURN GetLoadedIL()->GetDataRva(
1129             dac_cast<TADDR>(signature));
1130 }
1131
1132 inline CHECK PEFile::CheckSignature(PCCOR_SIGNATURE signature)
1133 {
1134     CONTRACT_CHECK
1135     {
1136         INSTANCE_CHECK;
1137         PRECONDITION(!IsDynamic() || signature == NULL);
1138         PRECONDITION(!IsResource());
1139         PRECONDITION(CheckLoaded());
1140         NOTHROW;
1141         GC_NOTRIGGER;
1142         MODE_ANY;
1143     }
1144     CONTRACT_CHECK_END;
1145         
1146     CHECK(GetLoadedIL()->CheckData(signature,NULL_OK));
1147     CHECK_OK;
1148 }
1149
1150 inline CHECK PEFile::CheckSignatureRva(RVA signature)
1151 {
1152     CONTRACT_CHECK
1153     {
1154         INSTANCE_CHECK;
1155         PRECONDITION(!IsDynamic() || signature == NULL);
1156         PRECONDITION(!IsResource());
1157         PRECONDITION(CheckLoaded());
1158         NOTHROW;
1159         GC_NOTRIGGER;
1160         MODE_ANY;
1161     }
1162     CONTRACT_CHECK_END;
1163         
1164     CHECK(GetLoadedIL()->CheckRva(signature,NULL_OK));
1165     CHECK_OK;
1166 }
1167
1168 inline IMAGE_COR_VTABLEFIXUP *PEFile::GetVTableFixups(COUNT_T *pCount/*=NULL*/)
1169 {
1170     CONTRACT(IMAGE_COR_VTABLEFIXUP *)
1171     {
1172         PRECONDITION(CheckLoaded());
1173         INSTANCE_CHECK;
1174         NOTHROW;
1175         GC_NOTRIGGER;
1176         MODE_ANY;
1177         POSTCONDITION(CheckPointer(RETVAL, NULL_OK));
1178     }
1179     CONTRACT_END;
1180
1181     if (IsResource() || IsDynamic() || IsILOnly())
1182     {
1183         if (pCount != NULL)
1184             *pCount = 0;
1185         RETURN NULL;
1186     }
1187     else
1188         RETURN GetLoadedIL()->GetVTableFixups(pCount);
1189 }
1190
1191 inline void *PEFile::GetVTable(RVA rva)
1192 {
1193     CONTRACT(void *)
1194     {
1195         INSTANCE_CHECK;
1196         PRECONDITION(!IsDynamic());
1197         PRECONDITION(!IsResource());
1198         PRECONDITION(CheckLoaded());
1199         PRECONDITION(!IsILOnly());
1200         PRECONDITION(GetLoadedIL()->CheckRva(rva));
1201         NOTHROW;
1202         GC_NOTRIGGER;
1203         MODE_ANY;
1204         POSTCONDITION(CheckPointer(RETVAL));
1205     }
1206     CONTRACT_END;
1207
1208     RETURN (void *)GetLoadedIL()->GetRvaData(rva);
1209 }
1210
1211 // @todo: this is bad to expose. But it is needed to support current IJW thunks
1212 inline HMODULE PEFile::GetIJWBase()
1213 {
1214     CONTRACTL
1215     {
1216         INSTANCE_CHECK;
1217         PRECONDITION(!IsDynamic());
1218         PRECONDITION(!IsResource());
1219         PRECONDITION(CheckLoaded());
1220         PRECONDITION(!IsILOnly());
1221         NOTHROW;
1222         GC_NOTRIGGER;
1223         MODE_ANY;
1224     }
1225     CONTRACTL_END;
1226
1227     return (HMODULE) dac_cast<TADDR>(GetLoadedIL()->GetBase());
1228 }
1229
1230 inline PTR_VOID PEFile::GetDebuggerContents(COUNT_T *pSize/*=NULL*/)
1231 {
1232     CONTRACT(PTR_VOID)
1233     {
1234         INSTANCE_CHECK;
1235         PRECONDITION(CheckPointer(pSize, NULL_OK));
1236         WRAPPER(THROWS);
1237         WRAPPER(GC_TRIGGERS);
1238         MODE_ANY;
1239         POSTCONDITION(CheckPointer(RETVAL, NULL_OK));
1240     }
1241     CONTRACT_END;
1242
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.
1246
1247     if (IsLoaded())
1248     {
1249         if (pSize != NULL)
1250             *pSize = GetLoaded()->GetSize();
1251
1252         RETURN GetLoaded()->GetBase();
1253     }
1254     else
1255     {
1256         if (pSize != NULL)
1257             *pSize = 0;
1258
1259         RETURN NULL;
1260     }
1261 }
1262
1263 inline PTR_CVOID PEFile::GetLoadedImageContents(COUNT_T *pSize/*=NULL*/)
1264 {
1265     CONTRACTL
1266     {
1267         INSTANCE_CHECK;
1268         THROWS;
1269         GC_TRIGGERS;
1270         MODE_ANY;
1271         SUPPORTS_DAC;
1272     }
1273     CONTRACTL_END;
1274
1275     if (IsLoaded() && !IsDynamic())
1276     {
1277         if (pSize != NULL)
1278         {
1279             *pSize = GetLoaded()->GetSize();
1280         }
1281         return GetLoaded()->GetBase();
1282     }
1283     else
1284     {
1285         if (pSize != NULL)
1286         {
1287             *pSize = 0;
1288         }
1289         return NULL;
1290     }
1291 }
1292
1293 #ifndef DACCESS_COMPILE
1294 inline const void *PEFile::GetManagedFileContents(COUNT_T *pSize/*=NULL*/)
1295 {
1296     CONTRACT(const void *)
1297     {
1298         INSTANCE_CHECK;
1299         PRECONDITION(CheckLoaded());
1300         WRAPPER(THROWS);
1301         WRAPPER(GC_TRIGGERS);
1302         MODE_ANY;
1303         POSTCONDITION((!GetLoaded()->GetSize()) || CheckPointer(RETVAL));
1304     }
1305     CONTRACT_END;
1306
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.
1309     LoadLibrary(FALSE);
1310
1311     if (pSize != NULL)
1312         *pSize = GetLoadedIL()->GetSize();
1313
1314     
1315     RETURN GetLoadedIL()->GetBase();
1316 }
1317 #endif // DACCESS_COMPILE
1318
1319 inline BOOL PEFile::IsPtrInILImage(PTR_CVOID data)
1320 {
1321     CONTRACTL
1322     {
1323         INSTANCE_CHECK;
1324         NOTHROW;
1325         GC_NOTRIGGER;
1326         FORBID_FAULT;
1327         SO_TOLERANT;
1328         SUPPORTS_DAC;
1329     }
1330     CONTRACTL_END;
1331
1332     if (HasOpenedILimage())
1333     {
1334 #if defined(FEATURE_PREJIT)
1335         if (m_openedILimage == m_nativeImage)
1336         {
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));
1347         }
1348 #endif // defined(FEATURE_PREJIT) && defined(FEATURE_CORECLR)
1349         return GetOpenedILimage()->IsPtrInImage(data);
1350     }
1351     else
1352         return FALSE;
1353 }
1354 // ------------------------------------------------------------
1355 // Native image access
1356 // ------------------------------------------------------------
1357 inline BOOL PEFile::HasNativeImage()
1358 {
1359     CONTRACTL
1360     {
1361         INSTANCE_CHECK;
1362         NOTHROW;
1363         GC_NOTRIGGER;
1364         MODE_ANY;
1365         SO_TOLERANT;
1366         CANNOT_TAKE_LOCK;
1367         SUPPORTS_DAC;
1368     }
1369     CONTRACTL_END;
1370
1371 #ifdef FEATURE_PREJIT
1372     return (m_nativeImage != NULL);
1373 #else
1374     return FALSE;
1375 #endif
1376 }
1377
1378 inline PTR_PEImageLayout PEFile::GetLoadedIL() 
1379 {
1380     LIMITED_METHOD_CONTRACT;
1381     SUPPORTS_DAC;
1382
1383     _ASSERTE(HasOpenedILimage());
1384     if(IsIntrospectionOnly())
1385         return GetOpenedILimage()->GetLoadedIntrospectionLayout();
1386     
1387     return GetOpenedILimage()->GetLoadedLayout();
1388 };
1389
1390 inline PTR_PEImageLayout PEFile::GetAnyILWithRef() 
1391 {
1392     WRAPPER_NO_CONTRACT;
1393     return GetILimage()->GetLayout(PEImageLayout::LAYOUT_ANY,PEImage::LAYOUT_CREATEIFNEEDED);
1394 };
1395
1396
1397 inline BOOL PEFile::IsLoaded(BOOL bAllowNative/*=TRUE*/) 
1398 {
1399     CONTRACTL
1400     {
1401         NOTHROW;
1402         GC_NOTRIGGER;
1403         SO_TOLERANT;
1404         MODE_ANY;
1405     }
1406     CONTRACTL_END;
1407     if(IsDynamic())
1408         return TRUE;
1409     if(IsIntrospectionOnly())
1410     {
1411         return HasOpenedILimage() && GetOpenedILimage()->HasLoadedIntrospectionLayout();
1412     }
1413 #ifdef FEATURE_PREJIT
1414     if (bAllowNative && HasNativeImage())
1415     {
1416         PEImage *pNativeImage = GetPersistentNativeImage();
1417         return pNativeImage->HasLoadedLayout() && (pNativeImage->GetLoadedLayout()->IsNativeILILOnly() || (HasLoadedIL()));
1418     }
1419     else
1420 #endif
1421         return HasLoadedIL();
1422 };
1423
1424
1425 inline PTR_PEImageLayout PEFile::GetLoaded() 
1426 {
1427     WRAPPER_NO_CONTRACT;
1428     SUPPORTS_DAC;
1429     return HasNativeImage()?GetLoadedNative():GetLoadedIL();
1430 };
1431
1432 inline PTR_PEImageLayout PEFile::GetLoadedNative()
1433 {
1434     CONTRACTL
1435     {
1436         NOTHROW;
1437         GC_NOTRIGGER;
1438         SO_TOLERANT;
1439         MODE_ANY;
1440         SUPPORTS_DAC;
1441     }
1442     CONTRACTL_END;
1443
1444 #ifdef FEATURE_PREJIT
1445     PEImage* pImage=GetPersistentNativeImage();
1446     _ASSERTE(pImage && pImage->GetLoadedLayout());
1447     return pImage->GetLoadedLayout();
1448 #else
1449     // Should never get here
1450     PRECONDITION(HasNativeImage());
1451     return NULL;
1452 #endif
1453 };
1454
1455 #ifdef FEATURE_PREJIT
1456 inline PEImage *PEFile::GetPersistentNativeImage()
1457 {
1458     CONTRACT(PEImage *)
1459     {
1460         INSTANCE_CHECK;
1461         PRECONDITION(HasNativeImage());
1462         POSTCONDITION(CheckPointer(RETVAL));
1463         PRECONDITION(m_bHasPersistentMDImport);
1464         NOTHROW;
1465         GC_NOTRIGGER;
1466         MODE_ANY;
1467         SO_TOLERANT;
1468         CANNOT_TAKE_LOCK;
1469         SUPPORTS_DAC;
1470     }
1471     CONTRACT_END;
1472
1473     RETURN m_nativeImage;
1474 }
1475
1476 #ifndef DACCESS_COMPILE
1477 inline PEImage *PEFile::GetNativeImageWithRef()
1478 {
1479     CONTRACT(PEImage *)
1480     {
1481         INSTANCE_CHECK;
1482         NOTHROW;
1483         GC_TRIGGERS; 
1484         MODE_ANY;
1485         POSTCONDITION(CheckPointer(RETVAL,NULL_OK));
1486     }
1487     CONTRACT_END;
1488     GCX_PREEMP();
1489     SimpleReadLockHolder mdlock(m_pMetadataLock);
1490     if(m_nativeImage)
1491         m_nativeImage->AddRef();
1492     RETURN m_nativeImage;
1493 }
1494 #endif // DACCESS_COMPILE
1495
1496 inline BOOL PEFile::HasNativeImageMetadata()
1497 {
1498     CONTRACT(BOOL)
1499     {
1500         INSTANCE_CHECK;
1501         NOTHROW;
1502         GC_NOTRIGGER;
1503         MODE_ANY;
1504         SO_TOLERANT;
1505         SUPPORTS_DAC;
1506     }
1507     CONTRACT_END;
1508
1509     RETURN ((m_flags & PEFILE_HAS_NATIVE_IMAGE_METADATA) != 0);
1510 }
1511 #endif
1512
1513  // Function to get the fully qualified name of an assembly
1514  inline void PEAssembly::GetFullyQualifiedAssemblyName(IMDInternalImport* pImport, mdAssembly mda, SString &result, DWORD flags)
1515 {
1516     CONTRACTL
1517     {
1518         PRECONDITION(CheckValue(result));
1519 #ifndef DACCESS_COMPILE
1520         THROWS;
1521 #else
1522         NOTHROW;
1523  #endif // !DACCESS_COMPILE
1524         GC_TRIGGERS;
1525         MODE_ANY;
1526     }
1527     CONTRACTL_END;
1528
1529     if(pImport != NULL)
1530     {
1531         // This is for DAC, ONLY for the binding tool.  Don't use for other
1532         // purposes, since this is not canonicalized through Fusion.
1533         LPCSTR name;
1534         AssemblyMetaDataInternal context;
1535         DWORD dwFlags;
1536         PBYTE pbPublicKey;
1537         DWORD cbPublicKey;
1538         if (FAILED(pImport->GetAssemblyProps(
1539             mda, 
1540             (const void **) &pbPublicKey, 
1541             &cbPublicKey, 
1542             NULL, 
1543             &name, 
1544             &context, 
1545             &dwFlags)))
1546         {
1547             _ASSERTE(!"If this fires, then we have to throw for corrupted images");
1548             result.SetUTF8("");
1549             return;
1550         }
1551         
1552         result.SetUTF8(name);
1553         
1554         result.AppendPrintf(W(", Version=%u.%u.%u.%u"),
1555                             context.usMajorVersion, context.usMinorVersion,
1556                             context.usBuildNumber, context.usRevisionNumber);
1557         
1558         result.Append(W(", Culture="));
1559         if (!*context.szLocale)
1560         {
1561             result.Append(W("neutral"));
1562         }
1563         else
1564         {
1565             result.AppendUTF8(context.szLocale);
1566         }
1567         
1568         if (cbPublicKey != 0)
1569         {
1570 #ifndef DACCESS_COMPILE
1571
1572             StrongNameBufferHolder<BYTE> pbToken;
1573             DWORD cbToken;
1574             CQuickBytes qb;
1575             
1576             if (StrongNameTokenFromPublicKey(pbPublicKey, cbPublicKey,
1577                                              &pbToken, &cbToken))
1578             {
1579                 // two hex digits per byte
1580                 WCHAR* szToken = (WCHAR*) qb.AllocNoThrow(sizeof(WCHAR) * (cbToken*2+1));
1581                 if (szToken)
1582                 {
1583 #define TOHEX(a) ((a)>=10 ? L'a'+(a)-10 : L'0'+(a))
1584                     UINT x;
1585                     UINT y;
1586                     for ( x = 0, y = 0; x < cbToken; ++x )
1587                     {
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 ); 
1592                     }
1593                     szToken[y] = L'\0';
1594                     
1595                     result.Append(W(", PublicKeyToken="));
1596                     result.Append(szToken);
1597 #undef TOHEX
1598                 }
1599             }
1600 #endif
1601
1602         }
1603         else
1604         {
1605             result.Append(W(", PublicKeyToken=null"));
1606         }
1607         
1608         if (dwFlags & afPA_Mask)
1609         {
1610             result.Append(W(", ProcessorArchitecture="));
1611             
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"));
1622         }
1623     }
1624 }
1625  
1626  
1627 // ------------------------------------------------------------
1628 // Descriptive strings
1629 // ------------------------------------------------------------
1630 inline void PEAssembly::GetDisplayName(SString &result, DWORD flags)
1631 {
1632     CONTRACTL
1633     {
1634         PRECONDITION(CheckValue(result));
1635 #ifndef DACCESS_COMPILE
1636         THROWS;
1637 #else
1638         NOTHROW;
1639 #endif // DACCESS_COMPILE
1640         GC_TRIGGERS;
1641         MODE_ANY;
1642     }
1643     CONTRACTL_END;
1644  
1645 #ifndef DACCESS_COMPILE
1646
1647 #ifdef FEATURE_FUSION
1648     FusionBind::GetAssemblyNameDisplayName(GetFusionAssemblyName(), result, flags);
1649 #else
1650     if ((flags == (ASM_DISPLAYF_VERSION | ASM_DISPLAYF_CULTURE | ASM_DISPLAYF_PUBLIC_KEY_TOKEN)) &&
1651         !m_sTextualIdentity.IsEmpty())
1652     {
1653         result.Set(m_sTextualIdentity);
1654     }
1655     else
1656     {
1657         AssemblySpec spec;
1658         spec.InitializeSpec(this);
1659         spec.GetFileOrDisplayName(flags, result);
1660     }
1661 #endif // FEATURE_FUSION
1662
1663 #else
1664     IMDInternalImport *pImport = GetMDImport();
1665     GetFullyQualifiedAssemblyName(pImport, TokenFromRid(1, mdtAssembly), result, flags);
1666 #endif //DACCESS_COMPILE
1667 }
1668
1669 // ------------------------------------------------------------
1670 // Metadata access
1671 // ------------------------------------------------------------
1672
1673 inline LPCSTR PEAssembly::GetSimpleName()
1674 {
1675     CONTRACTL
1676     {
1677         NOTHROW;
1678         if (!m_bHasPersistentMDImport) { GC_TRIGGERS;} else {DISABLED(GC_TRIGGERS);};
1679         MODE_ANY;
1680         SUPPORTS_DAC;
1681     }
1682     CONTRACTL_END;
1683     
1684     LPCSTR name = "";
1685     IMDInternalImportHolder pImport = GetMDImport();
1686     if (pImport != NULL)
1687     {
1688         if (FAILED(pImport->GetAssemblyProps(TokenFromRid(1, mdtAssembly), NULL, NULL, NULL, &name, NULL, NULL)))
1689         {
1690             _ASSERTE(!"If this fires, then we have to throw for corrupted images");
1691             name = "";
1692         }
1693     }
1694     return name;
1695 }
1696
1697 inline BOOL PEFile::IsStrongNamed()
1698 {
1699     CONTRACTL
1700     {
1701         THROWS;
1702         WRAPPER(GC_NOTRIGGER);
1703         MODE_ANY;
1704     }
1705     CONTRACTL_END;
1706     
1707     DWORD flags = 0;
1708     IfFailThrow(GetMDImport()->GetAssemblyProps(TokenFromRid(1, mdtAssembly), NULL, NULL, NULL, NULL, NULL, &flags));
1709     return (flags & afPublicKey) != NULL;
1710 }
1711
1712
1713 //---------------------------------------------------------------------------------------
1714 //
1715 // Check to see if this assembly has had its strong name signature verified yet.
1716 //
1717
1718 inline BOOL PEFile::IsStrongNameVerified()
1719 {
1720     LIMITED_METHOD_CONTRACT;
1721     return m_fStrongNameVerified;
1722 }
1723
1724 inline const void *PEFile::GetPublicKey(DWORD *pcbPK)
1725 {
1726     CONTRACTL
1727     {
1728         PRECONDITION(CheckPointer(pcbPK, NULL_OK));
1729         THROWS;
1730         WRAPPER(GC_TRIGGERS);
1731         MODE_ANY;
1732     }
1733     CONTRACTL_END;
1734     
1735     const void *pPK;
1736     IfFailThrow(GetMDImport()->GetAssemblyProps(TokenFromRid(1, mdtAssembly), &pPK, pcbPK, NULL, NULL, NULL, NULL));
1737     return pPK;
1738 }
1739
1740 inline ULONG PEFile::GetHashAlgId()
1741 {
1742     CONTRACTL
1743     {
1744         THROWS;
1745         WRAPPER(GC_TRIGGERS);
1746         MODE_ANY;
1747     }
1748     CONTRACTL_END;
1749     
1750     ULONG hashAlgId;
1751     IfFailThrow(GetMDImport()->GetAssemblyProps(TokenFromRid(1, mdtAssembly), NULL, NULL, &hashAlgId, NULL, NULL, NULL));
1752     return hashAlgId;
1753 }
1754
1755 inline LPCSTR PEFile::GetLocale()
1756 {
1757     CONTRACTL
1758     {
1759         THROWS;
1760         WRAPPER(GC_NOTRIGGER);
1761         MODE_ANY;
1762     }
1763     CONTRACTL_END;
1764     
1765     AssemblyMetaDataInternal md;
1766     IfFailThrow(GetMDImport()->GetAssemblyProps(TokenFromRid(1, mdtAssembly), NULL, NULL, NULL, NULL, &md, NULL));
1767     return md.szLocale;
1768 }
1769
1770 inline DWORD PEFile::GetFlags()
1771 {
1772     CONTRACTL
1773     {
1774         PRECONDITION(IsAssembly());
1775         INSTANCE_CHECK;
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()); }
1779         MODE_ANY;
1780     }
1781     CONTRACTL_END;
1782
1783     DWORD flags;
1784     IfFailThrow(GetMDImport()->GetAssemblyProps(TokenFromRid(1, mdtAssembly), NULL, NULL, NULL, NULL, NULL, &flags));
1785     return flags;
1786 }
1787
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)
1791 {
1792     CONTRACTL
1793     {
1794         PRECONDITION(IsAssembly());
1795         INSTANCE_CHECK;
1796         NOTHROW;
1797         GC_NOTRIGGER;
1798         FORBID_FAULT;
1799         MODE_ANY;
1800     }
1801     CONTRACTL_END;
1802
1803     _ASSERTE (pdwFlags != NULL);
1804
1805     if (!m_bHasPersistentMDImport)
1806         return E_FAIL;
1807
1808     return GetPersistentMDImport()->GetAssemblyProps(TokenFromRid(1, mdtAssembly), NULL, NULL, NULL, NULL, NULL, pdwFlags);
1809 }
1810
1811 #ifdef FEATURE_CAS_POLICY
1812 inline COR_TRUST *PEFile::GetAuthenticodeSignature()
1813 {
1814     CONTRACTL
1815     {
1816         THROWS;
1817         GC_TRIGGERS;
1818         MODE_PREEMPTIVE;
1819     }
1820     CONTRACTL_END;
1821
1822     if (!m_fCheckedCertificate && HasSecurityDirectory())
1823     {
1824         CheckAuthenticodeSignature();
1825     }
1826
1827     return m_certificate;
1828 }
1829 #endif
1830
1831 // ------------------------------------------------------------
1832 // Hash support
1833 // ------------------------------------------------------------
1834
1835 inline BOOL PEAssembly::HasStrongNameSignature()
1836 {
1837     WRAPPER_NO_CONTRACT;
1838
1839     if (IsDynamic())
1840         return FALSE;
1841
1842 #ifdef FEATURE_PREJIT
1843     if (IsNativeLoaded())
1844     {
1845         CONSISTENCY_CHECK(HasNativeImage());
1846
1847         // The NGen images do not have strong name signature
1848         return FALSE;
1849     }
1850 #endif // FEATURE_PREJIT
1851
1852     return GetILimage()->HasStrongNameSignature();
1853 }
1854
1855 //---------------------------------------------------------------------------------------
1856 //
1857 // Check to see that an assembly is not delay or test signed
1858 //
1859
1860 inline BOOL PEAssembly::IsFullySigned()
1861 {
1862     WRAPPER_NO_CONTRACT;
1863
1864 #ifdef FEATURE_PREJIT
1865     if (IsNativeLoaded())
1866     {
1867         CONSISTENCY_CHECK(HasNativeImage());
1868
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.
1873         //
1874         // Note that this is consistent with other abstractions at the PEFile level such as
1875         // HasStrongNameSignature()
1876         return IsStrongNamed();
1877     } else
1878 #endif // FEATURE_PREJIT
1879     if (HasOpenedILimage())
1880     {
1881         return GetOpenedILimage()->IsStrongNameSigned();
1882     }
1883     else
1884     {
1885         return FALSE;
1886     }
1887 }
1888
1889
1890 #ifdef FEATURE_CAS_POLICY
1891 //---------------------------------------------------------------------------------------
1892 //
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.
1896 // 
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.
1901 // 
1902 // See code:AssemblySecurityDescriptor::ResolveWorker#StrongNameBypass
1903 //
1904
1905 inline void PEAssembly::DoLoadSignatureChecks()
1906 {
1907     CONTRACTL
1908     {
1909         THROWS;
1910         GC_TRIGGERS; // Fusion uses crsts on AddRef/Release
1911         MODE_ANY;
1912     }
1913     CONTRACTL_END;
1914
1915     ETWOnStartup(SecurityCatchCall_V1, SecurityCatchCallEnd_V1);
1916
1917     // If this isn't mscorlib or a dynamic assembly, verify the Authenticode signature.
1918     if (IsSystem() || IsDynamic())
1919     {
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;
1922     }
1923
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
1926     // the assembly is.
1927     // 
1928     // For more information see code:AssemblySecurityDescriptor::ResolveWorker#StrongNameBypass
1929
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());
1934
1935     if (!g_pConfig->BypassTrustedAppStrongNames())
1936     { 
1937         VerifyStrongName();
1938     }
1939 }
1940 #endif // FEATURE_CAS_POLICY
1941
1942 // ------------------------------------------------------------
1943 // Metadata access
1944 // ------------------------------------------------------------
1945 #ifdef FEATURE_MULTIMODULE_ASSEMBLIES
1946 inline PEAssembly *PEModule::GetAssembly()
1947 {
1948     CONTRACT(PEAssembly *)
1949     {
1950         POSTCONDITION(CheckPointer(RETVAL));
1951         NOTHROW;
1952         GC_NOTRIGGER;
1953         MODE_ANY;
1954         CANNOT_TAKE_LOCK;
1955         SO_TOLERANT;
1956         SUPPORTS_DAC;
1957     }
1958     CONTRACT_END;
1959
1960     RETURN m_assembly;
1961 }
1962
1963 inline BOOL PEModule::IsResource()
1964 {
1965     CONTRACTL
1966     {
1967         NOTHROW;
1968         GC_NOTRIGGER;
1969         MODE_ANY;
1970         SO_TOLERANT;
1971         SUPPORTS_DAC;
1972     }
1973     CONTRACTL_END;
1974 #ifdef DACCESS_COMPILE
1975     _ASSERTE(m_bIsResource!=-1);
1976 #else
1977     if (m_bIsResource==-1)
1978     {
1979         DWORD flags;
1980         if (FAILED(m_assembly->GetPersistentMDImport()->GetFileProps(m_token, NULL, NULL, NULL, &flags)))
1981         {
1982             _ASSERTE(!"If this fires, then we have to throw for corrupted images");
1983             flags = 0;
1984         }
1985         m_bIsResource=((flags & ffContainsNoMetaData) != 0);
1986     }
1987 #endif
1988     
1989     return m_bIsResource;
1990 }
1991
1992 inline LPCUTF8 PEModule::GetSimpleName()
1993 {
1994     CONTRACT(LPCUTF8)
1995     {
1996         POSTCONDITION(CheckPointer(RETVAL));
1997         POSTCONDITION(strlen(RETVAL) > 0);
1998         NOTHROW;
1999         GC_NOTRIGGER;
2000         MODE_ANY;
2001         SO_TOLERANT;
2002         SUPPORTS_DAC;
2003     }
2004     CONTRACT_END;
2005     
2006     LPCUTF8 name;
2007     
2008     if (FAILED(m_assembly->GetPersistentMDImport()->GetFileProps(m_token, &name, NULL, NULL, NULL)))
2009     {
2010         _ASSERTE(!"If this fires, then we have to throw for corrupted images");
2011         name = "";
2012     }
2013     
2014     RETURN name;
2015 }
2016
2017 inline mdFile PEModule::GetToken()
2018 {
2019     LIMITED_METHOD_CONTRACT;
2020     return m_token;
2021 }
2022 #endif // FEATURE_MULTIMODULE_ASSEMBLIES
2023
2024 #ifndef DACCESS_COMPILE
2025 inline void PEFile::RestoreMDImport(IMDInternalImport* pImport)
2026 {
2027     CONTRACTL
2028     {
2029         MODE_ANY;
2030         GC_NOTRIGGER;
2031         NOTHROW;
2032         FORBID_FAULT;
2033     }
2034     CONTRACTL_END;
2035     
2036     _ASSERTE(m_pMetadataLock->LockTaken() && m_pMetadataLock->IsWriterLock());
2037     if (m_pMDImport != NULL)
2038         return;
2039     m_pMDImport=pImport;
2040     if(m_pMDImport)
2041         m_pMDImport->AddRef();
2042 }
2043 #endif
2044 inline void PEFile::OpenMDImport()
2045 {
2046     WRAPPER_NO_CONTRACT;
2047     //need synchronization
2048     _ASSERTE(m_pMetadataLock->LockTaken() && m_pMetadataLock->IsWriterLock());
2049     OpenMDImport_Unsafe();
2050 }
2051
2052 inline PEFile* PEFile::Dummy()
2053 {
2054     return (PEFile*)(-1);
2055 }
2056
2057 inline bool PEAssembly::HasBindableIdentity()
2058 {
2059     CONTRACTL
2060     {
2061         INSTANCE_CHECK;
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()); }
2065         MODE_ANY;
2066         SUPPORTS_DAC;
2067     }
2068     CONTRACTL_END
2069
2070     return !IsAfContentType_WindowsRuntime(GetFlags());
2071 }
2072
2073 inline bool PEAssembly::IsWindowsRuntime()
2074 {
2075     CONTRACTL
2076     {
2077         THROWS;
2078         GC_TRIGGERS;
2079         MODE_ANY;
2080     }
2081     CONTRACTL_END;
2082     
2083     return IsAfContentType_WindowsRuntime(GetFlags());
2084 }
2085
2086 #endif  // PEFILE_INL_