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// PEDecoder.inl
6//
7
8// --------------------------------------------------------------------------------
9
10#ifndef _PEDECODER_INL_
11#define _PEDECODER_INL_
12
13#include "pedecoder.h"
14#include "ex.h"
15
16#ifndef DACCESS_COMPILE
17
18inline PEDecoder::PEDecoder()
19 : m_base(0),
20 m_size(0),
21 m_flags(0),
22 m_pNTHeaders(nullptr),
23 m_pCorHeader(nullptr),
24 m_pNativeHeader(nullptr),
25 m_pReadyToRunHeader(nullptr)
26{
27 CONTRACTL
28 {
29 CONSTRUCTOR_CHECK;
30 NOTHROW;
31 CANNOT_TAKE_LOCK;
32 GC_NOTRIGGER;
33 }
34 CONTRACTL_END;
35}
36#else
37inline PEDecoder::PEDecoder()
38{
39 LIMITED_METHOD_CONTRACT;
40}
41#endif // #ifndef DACCESS_COMPILE
42
43inline PTR_VOID PEDecoder::GetBase() const
44{
45 LIMITED_METHOD_CONTRACT;
46 SUPPORTS_DAC;
47
48 return PTR_VOID(m_base);
49}
50
51inline BOOL PEDecoder::IsMapped() const
52{
53 LIMITED_METHOD_CONTRACT;
54 SUPPORTS_DAC;
55
56 return (m_flags & FLAG_MAPPED) != 0;
57}
58
59inline BOOL PEDecoder::IsRelocated() const
60{
61 LIMITED_METHOD_CONTRACT;
62
63 return (m_flags & FLAG_RELOCATED) != 0;
64}
65
66inline void PEDecoder::SetRelocated()
67{
68 m_flags |= FLAG_RELOCATED;
69}
70
71inline BOOL PEDecoder::IsFlat() const
72{
73 LIMITED_METHOD_CONTRACT;
74
75 return HasContents() && !IsMapped();
76}
77
78inline BOOL PEDecoder::HasContents() const
79{
80 LIMITED_METHOD_CONTRACT;
81 SUPPORTS_DAC;
82
83 return (m_flags & FLAG_CONTENTS) != 0;
84}
85
86inline COUNT_T PEDecoder::GetSize() const
87{
88 LIMITED_METHOD_DAC_CONTRACT;
89
90 return m_size;
91}
92
93inline PEDecoder::PEDecoder(PTR_VOID mappedBase, bool fixedUp /*= FALSE*/)
94 : m_base(dac_cast<TADDR>(mappedBase)),
95 m_size(0),
96 m_flags(FLAG_MAPPED | FLAG_CONTENTS | FLAG_NT_CHECKED | (fixedUp ? FLAG_RELOCATED : 0)),
97 m_pNTHeaders(nullptr),
98 m_pCorHeader(nullptr),
99 m_pNativeHeader(nullptr),
100 m_pReadyToRunHeader(nullptr)
101{
102 CONTRACTL
103 {
104 CONSTRUCTOR_CHECK;
105 PRECONDITION(CheckPointer(mappedBase));
106 PRECONDITION(CheckAligned(mappedBase, GetOsPageSize()));
107 PRECONDITION(PEDecoder(mappedBase,fixedUp).CheckNTHeaders());
108 THROWS;
109 GC_NOTRIGGER;
110 SO_TOLERANT;
111 SUPPORTS_DAC;
112 }
113 CONTRACTL_END;
114
115 // Temporarily set the size to 2 pages, so we can get the headers.
116 m_size = GetOsPageSize()*2;
117
118 m_pNTHeaders = PTR_IMAGE_NT_HEADERS(FindNTHeaders());
119 if (!m_pNTHeaders)
120 ThrowHR(COR_E_BADIMAGEFORMAT);
121
122 m_size = VAL32(m_pNTHeaders->OptionalHeader.SizeOfImage);
123}
124
125#ifndef DACCESS_COMPILE
126
127//REM
128//what's the right way to do this?
129//we want to use some against TADDR, but also want to do
130//some against what's just in the current process.
131//m_base is a TADDR in DAC all the time, though.
132//Have to implement separate fn to do the lookup??
133inline PEDecoder::PEDecoder(void *flatBase, COUNT_T size)
134 : m_base((TADDR)flatBase),
135 m_size(size),
136 m_flags(FLAG_CONTENTS),
137 m_pNTHeaders(NULL),
138 m_pCorHeader(NULL),
139 m_pNativeHeader(NULL),
140 m_pReadyToRunHeader(NULL)
141{
142 CONTRACTL
143 {
144 CONSTRUCTOR_CHECK;
145 PRECONDITION(CheckPointer(flatBase));
146 NOTHROW;
147 GC_NOTRIGGER;
148 CANNOT_TAKE_LOCK;
149 }
150 CONTRACTL_END;
151}
152
153inline void PEDecoder::Init(void *flatBase, COUNT_T size)
154{
155 CONTRACTL
156 {
157 INSTANCE_CHECK;
158 PRECONDITION((size == 0) || CheckPointer(flatBase));
159 PRECONDITION(!HasContents());
160 NOTHROW;
161 GC_NOTRIGGER;
162 }
163 CONTRACTL_END;
164
165 m_base = (TADDR)flatBase;
166 m_size = size;
167 m_flags = FLAG_CONTENTS;
168}
169
170
171
172inline HRESULT PEDecoder::Init(void *mappedBase, bool fixedUp /*= FALSE*/)
173{
174 CONTRACTL
175 {
176 INSTANCE_CHECK;
177 NOTHROW;
178 GC_NOTRIGGER;
179 PRECONDITION(CheckPointer(mappedBase));
180 PRECONDITION(CheckAligned(mappedBase, GetOsPageSize()));
181 PRECONDITION(!HasContents());
182 }
183 CONTRACTL_END;
184
185 m_base = (TADDR)mappedBase;
186 m_flags = FLAG_MAPPED | FLAG_CONTENTS;
187 if (fixedUp)
188 m_flags |= FLAG_RELOCATED;
189
190 // Temporarily set the size to 2 pages, so we can get the headers.
191 m_size = GetOsPageSize()*2;
192
193 m_pNTHeaders = FindNTHeaders();
194 if (!m_pNTHeaders)
195 return COR_E_BADIMAGEFORMAT;
196
197 m_size = VAL32(m_pNTHeaders->OptionalHeader.SizeOfImage);
198 return S_OK;
199}
200
201inline void PEDecoder::Reset()
202{
203 CONTRACTL
204 {
205 INSTANCE_CHECK;
206 NOTHROW;
207 GC_NOTRIGGER;
208 }
209 CONTRACTL_END;
210 m_base=NULL;
211 m_flags=NULL;
212 m_size=NULL;
213 m_pNTHeaders=NULL;
214 m_pCorHeader=NULL;
215 m_pNativeHeader=NULL;
216 m_pReadyToRunHeader=NULL;
217}
218#endif // #ifndef DACCESS_COMPILE
219
220
221inline IMAGE_NT_HEADERS32 *PEDecoder::GetNTHeaders32() const
222{
223 WRAPPER_NO_CONTRACT;
224 SUPPORTS_DAC;
225 return dac_cast<PTR_IMAGE_NT_HEADERS32>(FindNTHeaders());
226}
227
228inline IMAGE_NT_HEADERS64 *PEDecoder::GetNTHeaders64() const
229{
230 WRAPPER_NO_CONTRACT;
231 SUPPORTS_DAC;
232 return dac_cast<PTR_IMAGE_NT_HEADERS64>(FindNTHeaders());
233}
234
235inline BOOL PEDecoder::Has32BitNTHeaders() const
236{
237 CONTRACTL
238 {
239 INSTANCE_CHECK;
240 PRECONDITION(HasNTHeaders());
241 NOTHROW;
242 GC_NOTRIGGER;
243 SO_TOLERANT;
244 SUPPORTS_DAC;
245 CANNOT_TAKE_LOCK;
246 SUPPORTS_DAC;
247 }
248 CONTRACTL_END;
249
250 return (FindNTHeaders()->OptionalHeader.Magic == VAL16(IMAGE_NT_OPTIONAL_HDR32_MAGIC));
251}
252
253inline const void *PEDecoder::GetHeaders(COUNT_T *pSize) const
254{
255 CONTRACT(const void *)
256 {
257 INSTANCE_CHECK;
258 PRECONDITION(CheckNTHeaders());
259 NOTHROW;
260 GC_NOTRIGGER;
261 POSTCONDITION(CheckPointer(RETVAL));
262 }
263 CONTRACT_END;
264
265 //even though some data in OptionalHeader is different for 32 and 64, this field is the same
266 if (pSize != NULL)
267 *pSize = VAL32(FindNTHeaders()->OptionalHeader.SizeOfHeaders);
268
269 RETURN (const void *) m_base;
270}
271
272inline BOOL PEDecoder::IsDll() const
273{
274 CONTRACTL
275 {
276 INSTANCE_CHECK;
277 PRECONDITION(CheckNTHeaders());
278 NOTHROW;
279 GC_NOTRIGGER;
280 SUPPORTS_DAC;
281 }
282 CONTRACTL_END;
283
284 return ((FindNTHeaders()->FileHeader.Characteristics & VAL16(IMAGE_FILE_DLL)) != 0);
285}
286
287inline BOOL PEDecoder::HasBaseRelocations() const
288{
289 CONTRACTL
290 {
291 INSTANCE_CHECK;
292 PRECONDITION(CheckNTHeaders());
293 NOTHROW;
294 GC_NOTRIGGER;
295 }
296 CONTRACTL_END;
297
298 return ((FindNTHeaders()->FileHeader.Characteristics & VAL16(IMAGE_FILE_RELOCS_STRIPPED)) == 0);
299}
300
301inline const void *PEDecoder::GetPreferredBase() const
302{
303 CONTRACT(const void *)
304 {
305 INSTANCE_CHECK;
306 PRECONDITION(CheckNTHeaders());
307 NOTHROW;
308 GC_NOTRIGGER;
309 SO_TOLERANT;
310 POSTCONDITION(CheckPointer(RETVAL, NULL_OK));
311 }
312 CONTRACT_END;
313
314 if (Has32BitNTHeaders())
315 RETURN (const void *) (SIZE_T) VAL32(GetNTHeaders32()->OptionalHeader.ImageBase);
316 else
317 RETURN (const void *) (SIZE_T) VAL64(GetNTHeaders64()->OptionalHeader.ImageBase);
318}
319
320inline COUNT_T PEDecoder::GetVirtualSize() const
321{
322 CONTRACTL
323 {
324 INSTANCE_CHECK;
325 PRECONDITION(CheckNTHeaders());
326 NOTHROW;
327 GC_NOTRIGGER;
328 SUPPORTS_DAC;
329 SO_TOLERANT;
330 }
331 CONTRACTL_END;
332
333 //even though some data in OptionalHeader is different for 32 and 64, this field is the same
334 return VAL32(FindNTHeaders()->OptionalHeader.SizeOfImage);
335}
336
337inline WORD PEDecoder::GetSubsystem() const
338{
339 CONTRACTL
340 {
341 INSTANCE_CHECK;
342 PRECONDITION(CheckNTHeaders());
343 NOTHROW;
344 GC_NOTRIGGER;
345 SUPPORTS_DAC;
346 SO_TOLERANT;
347 }
348 CONTRACTL_END;
349
350 //even though some data in OptionalHeader is different for 32 and 64, this field is the same
351 return VAL16(FindNTHeaders()->OptionalHeader.Subsystem);
352}
353
354inline WORD PEDecoder::GetDllCharacteristics() const
355{
356 CONTRACTL
357 {
358 INSTANCE_CHECK;
359 PRECONDITION(CheckNTHeaders());
360 NOTHROW;
361 GC_NOTRIGGER;
362 SO_TOLERANT;
363 }
364 CONTRACTL_END;
365
366 //even though some data in OptionalHeader is different for 32 and 64, this field is the same
367 return VAL16(FindNTHeaders()->OptionalHeader.DllCharacteristics);
368}
369
370inline DWORD PEDecoder::GetTimeDateStamp() const
371{
372 CONTRACTL
373 {
374 INSTANCE_CHECK;
375 PRECONDITION(CheckNTHeaders());
376 NOTHROW;
377 GC_NOTRIGGER;
378 }
379 CONTRACTL_END;
380
381 return VAL32(FindNTHeaders()->FileHeader.TimeDateStamp);
382}
383
384inline DWORD PEDecoder::GetCheckSum() const
385{
386 CONTRACTL
387 {
388 INSTANCE_CHECK;
389 PRECONDITION(CheckNTHeaders());
390 NOTHROW;
391 GC_NOTRIGGER;
392 }
393 CONTRACTL_END;
394
395 //even though some data in OptionalHeader is different for 32 and 64, this field is the same
396 return VAL32(FindNTHeaders()->OptionalHeader.CheckSum);
397}
398
399inline DWORD PEDecoder::GetFileAlignment() const
400{
401 CONTRACTL
402 {
403 INSTANCE_CHECK;
404 PRECONDITION(CheckNTHeaders());
405 NOTHROW;
406 GC_NOTRIGGER;
407 }
408 CONTRACTL_END;
409
410 //even though some data in OptionalHeader is different for 32 and 64, this field is the same
411 return VAL32(FindNTHeaders()->OptionalHeader.FileAlignment);
412}
413
414inline DWORD PEDecoder::GetSectionAlignment() const
415{
416 CONTRACTL
417 {
418 INSTANCE_CHECK;
419 PRECONDITION(CheckNTHeaders());
420 NOTHROW;
421 GC_NOTRIGGER;
422 }
423 CONTRACTL_END;
424
425 //even though some data in OptionalHeader is different for 32 and 64, this field is the same
426 return VAL32(FindNTHeaders()->OptionalHeader.SectionAlignment);
427}
428
429inline WORD PEDecoder::GetMachine() const
430{
431 CONTRACTL
432 {
433 INSTANCE_CHECK;
434 PRECONDITION(CheckNTHeaders());
435 NOTHROW;
436 GC_NOTRIGGER;
437 }
438 CONTRACTL_END;
439
440 return VAL16(FindNTHeaders()->FileHeader.Machine);
441}
442
443inline WORD PEDecoder::GetCharacteristics() const
444{
445 CONTRACTL
446 {
447 INSTANCE_CHECK;
448 PRECONDITION(CheckNTHeaders());
449 NOTHROW;
450 GC_NOTRIGGER;
451 }
452 CONTRACTL_END;
453
454 return VAL16(FindNTHeaders()->FileHeader.Characteristics);
455}
456
457inline SIZE_T PEDecoder::GetSizeOfStackReserve() const
458{
459 CONTRACTL
460 {
461 INSTANCE_CHECK;
462 PRECONDITION(CheckNTHeaders());
463 NOTHROW;
464 GC_NOTRIGGER;
465 }
466 CONTRACTL_END;
467
468 if (Has32BitNTHeaders())
469 return (SIZE_T) VAL32(GetNTHeaders32()->OptionalHeader.SizeOfStackReserve);
470 else
471 return (SIZE_T) VAL64(GetNTHeaders64()->OptionalHeader.SizeOfStackReserve);
472}
473
474
475inline SIZE_T PEDecoder::GetSizeOfStackCommit() const
476{
477 CONTRACTL
478 {
479 INSTANCE_CHECK;
480 PRECONDITION(CheckNTHeaders());
481 NOTHROW;
482 GC_NOTRIGGER;
483 }
484 CONTRACTL_END;
485
486 if (Has32BitNTHeaders())
487 return (SIZE_T) VAL32(GetNTHeaders32()->OptionalHeader.SizeOfStackCommit);
488 else
489 return (SIZE_T) VAL64(GetNTHeaders64()->OptionalHeader.SizeOfStackCommit);
490}
491
492
493inline SIZE_T PEDecoder::GetSizeOfHeapReserve() const
494{
495 CONTRACTL
496 {
497 INSTANCE_CHECK;
498 PRECONDITION(CheckNTHeaders());
499 NOTHROW;
500 GC_NOTRIGGER;
501 }
502 CONTRACTL_END;
503
504 if (Has32BitNTHeaders())
505 return (SIZE_T) VAL32(GetNTHeaders32()->OptionalHeader.SizeOfHeapReserve);
506 else
507 return (SIZE_T) VAL64(GetNTHeaders64()->OptionalHeader.SizeOfHeapReserve);
508}
509
510
511inline SIZE_T PEDecoder::GetSizeOfHeapCommit() const
512{
513 CONTRACTL
514 {
515 INSTANCE_CHECK;
516 PRECONDITION(CheckNTHeaders());
517 NOTHROW;
518 GC_NOTRIGGER;
519 }
520 CONTRACTL_END;
521
522 if (Has32BitNTHeaders())
523 return (SIZE_T) VAL32(GetNTHeaders32()->OptionalHeader.SizeOfHeapCommit);
524 else
525 return (SIZE_T) VAL64(GetNTHeaders64()->OptionalHeader.SizeOfHeapCommit);
526}
527
528inline UINT32 PEDecoder::GetLoaderFlags() const
529{
530 CONTRACTL
531 {
532 INSTANCE_CHECK;
533 PRECONDITION(CheckNTHeaders());
534 NOTHROW;
535 GC_NOTRIGGER;
536 }
537 CONTRACTL_END;
538
539 if (Has32BitNTHeaders())
540 return VAL32(GetNTHeaders32()->OptionalHeader.LoaderFlags);
541 else
542 return VAL32(GetNTHeaders64()->OptionalHeader.LoaderFlags);
543}
544
545inline UINT32 PEDecoder::GetWin32VersionValue() const
546{
547 CONTRACTL
548 {
549 INSTANCE_CHECK;
550 PRECONDITION(CheckNTHeaders());
551 NOTHROW;
552 GC_NOTRIGGER;
553 }
554 CONTRACTL_END;
555
556 if (Has32BitNTHeaders())
557 return VAL32(GetNTHeaders32()->OptionalHeader.Win32VersionValue);
558 else
559 return VAL32(GetNTHeaders64()->OptionalHeader.Win32VersionValue);
560}
561
562inline COUNT_T PEDecoder::GetNumberOfRvaAndSizes() const
563{
564 CONTRACTL
565 {
566 INSTANCE_CHECK;
567 PRECONDITION(CheckNTHeaders());
568 NOTHROW;
569 GC_NOTRIGGER;
570 }
571 CONTRACTL_END;
572
573 if (Has32BitNTHeaders())
574 return VAL32(GetNTHeaders32()->OptionalHeader.NumberOfRvaAndSizes);
575 else
576 return VAL32(GetNTHeaders64()->OptionalHeader.NumberOfRvaAndSizes);
577}
578
579inline BOOL PEDecoder::HasDirectoryEntry(int entry) const
580{
581 CONTRACTL
582 {
583 INSTANCE_CHECK;
584 PRECONDITION(CheckNTHeaders());
585 NOTHROW;
586 GC_NOTRIGGER;
587 SUPPORTS_DAC;
588 SO_TOLERANT;
589 }
590 CONTRACTL_END;
591
592 if (Has32BitNTHeaders())
593 return (GetNTHeaders32()->OptionalHeader.DataDirectory[entry].VirtualAddress != 0);
594 else
595 return (GetNTHeaders64()->OptionalHeader.DataDirectory[entry].VirtualAddress != 0);
596}
597
598inline IMAGE_DATA_DIRECTORY *PEDecoder::GetDirectoryEntry(int entry) const
599{
600 CONTRACT(IMAGE_DATA_DIRECTORY *)
601 {
602 INSTANCE_CHECK;
603 PRECONDITION(CheckNTHeaders());
604 NOTHROW;
605 GC_NOTRIGGER;
606 POSTCONDITION(CheckPointer(RETVAL));
607 SO_TOLERANT;
608 CANNOT_TAKE_LOCK;
609 SUPPORTS_DAC;
610 }
611 CONTRACT_END;
612
613 if (Has32BitNTHeaders())
614 RETURN dac_cast<PTR_IMAGE_DATA_DIRECTORY>(
615 dac_cast<TADDR>(GetNTHeaders32()) +
616 offsetof(IMAGE_NT_HEADERS32, OptionalHeader.DataDirectory) +
617 entry * sizeof(IMAGE_DATA_DIRECTORY));
618 else
619 RETURN dac_cast<PTR_IMAGE_DATA_DIRECTORY>(
620 dac_cast<TADDR>(GetNTHeaders64()) +
621 offsetof(IMAGE_NT_HEADERS64, OptionalHeader.DataDirectory) +
622 entry * sizeof(IMAGE_DATA_DIRECTORY));
623}
624
625inline TADDR PEDecoder::GetDirectoryEntryData(int entry, COUNT_T *pSize) const
626{
627 CONTRACT(TADDR)
628 {
629 INSTANCE_CHECK;
630 PRECONDITION(CheckNTHeaders());
631 PRECONDITION(CheckDirectoryEntry(entry, 0, NULL_OK));
632 PRECONDITION(CheckPointer(pSize, NULL_OK));
633 NOTHROW;
634 GC_NOTRIGGER;
635 POSTCONDITION(CheckPointer((void *)RETVAL, NULL_OK));
636 SO_TOLERANT;
637 CANNOT_TAKE_LOCK;
638 SUPPORTS_DAC;
639 }
640 CONTRACT_END;
641
642 IMAGE_DATA_DIRECTORY *pDir = GetDirectoryEntry(entry);
643
644 if (pSize != NULL)
645 *pSize = VAL32(pDir->Size);
646
647 RETURN GetDirectoryData(pDir);
648}
649
650inline TADDR PEDecoder::GetDirectoryData(IMAGE_DATA_DIRECTORY *pDir) const
651{
652 CONTRACT(TADDR)
653 {
654 INSTANCE_CHECK;
655 PRECONDITION(CheckNTHeaders());
656 PRECONDITION(CheckDirectory(pDir, 0, NULL_OK));
657 NOTHROW;
658 GC_NOTRIGGER;
659 SO_TOLERANT;
660 SUPPORTS_DAC;
661 POSTCONDITION(CheckPointer((void *)RETVAL, NULL_OK));
662 CANNOT_TAKE_LOCK;
663 }
664 CONTRACT_END;
665
666 RETURN GetRvaData(VAL32(pDir->VirtualAddress));
667}
668
669inline TADDR PEDecoder::GetDirectoryData(IMAGE_DATA_DIRECTORY *pDir, COUNT_T *pSize) const
670{
671 CONTRACT(TADDR)
672 {
673 INSTANCE_CHECK;
674 PRECONDITION(CheckNTHeaders());
675 PRECONDITION(CheckDirectory(pDir, 0, NULL_OK));
676 PRECONDITION(CheckPointer(pSize));
677 NOTHROW;
678 GC_NOTRIGGER;
679 SO_TOLERANT;
680 SUPPORTS_DAC;
681 POSTCONDITION(CheckPointer((void *)RETVAL, NULL_OK));
682 CANNOT_TAKE_LOCK;
683 }
684 CONTRACT_END;
685
686 *pSize = VAL32(pDir->Size);
687
688 RETURN GetRvaData(VAL32(pDir->VirtualAddress));
689}
690
691inline TADDR PEDecoder::GetInternalAddressData(SIZE_T address) const
692{
693 CONTRACT(TADDR)
694 {
695 INSTANCE_CHECK;
696 PRECONDITION(CheckNTHeaders());
697 PRECONDITION(CheckInternalAddress(address, NULL_OK));
698 NOTHROW;
699 GC_NOTRIGGER;
700 POSTCONDITION(CheckPointer((void *)RETVAL));
701 SO_TOLERANT;
702 }
703 CONTRACT_END;
704
705 RETURN GetRvaData(InternalAddressToRva(address));
706}
707
708inline BOOL PEDecoder::HasCorHeader() const
709{
710 CONTRACTL
711 {
712 INSTANCE_CHECK;
713 PRECONDITION(CheckNTHeaders());
714 NOTHROW;
715 SUPPORTS_DAC;
716 GC_NOTRIGGER;
717 SO_TOLERANT;
718 }
719 CONTRACTL_END;
720
721 return HasDirectoryEntry(IMAGE_DIRECTORY_ENTRY_COMHEADER);
722}
723
724inline BOOL PEDecoder::IsILOnly() const
725{
726 CONTRACTL
727 {
728 INSTANCE_CHECK;
729 PRECONDITION(HasCorHeader());
730 NOTHROW;
731 GC_NOTRIGGER;
732 SO_TOLERANT;
733 SUPPORTS_DAC;
734 }
735 CONTRACTL_END;
736
737 // Pretend that ready-to-run images are IL-only
738 return((GetCorHeader()->Flags & VAL32(COMIMAGE_FLAGS_ILONLY)) != 0) || HasReadyToRunHeader();
739}
740
741inline COUNT_T PEDecoder::RvaToOffset(RVA rva) const
742{
743 CONTRACTL
744 {
745 INSTANCE_CHECK;
746 PRECONDITION(CheckNTHeaders());
747 PRECONDITION(CheckRva(rva,NULL_OK));
748 NOTHROW;
749 CANNOT_TAKE_LOCK;
750 GC_NOTRIGGER;
751 SUPPORTS_DAC;
752 }
753 CONTRACTL_END;
754 if(rva > 0)
755 {
756 IMAGE_SECTION_HEADER *section = RvaToSection(rva);
757 if (section == NULL)
758 return rva;
759
760 return rva - VAL32(section->VirtualAddress) + VAL32(section->PointerToRawData);
761 }
762 else return 0;
763}
764
765inline RVA PEDecoder::OffsetToRva(COUNT_T fileOffset) const
766{
767 CONTRACTL
768 {
769 INSTANCE_CHECK;
770 PRECONDITION(CheckNTHeaders());
771 PRECONDITION(CheckOffset(fileOffset,NULL_OK));
772 NOTHROW;
773 GC_NOTRIGGER;
774 SUPPORTS_DAC;
775 }
776 CONTRACTL_END;
777 if(fileOffset > 0)
778 {
779 IMAGE_SECTION_HEADER *section = OffsetToSection(fileOffset);
780 PREFIX_ASSUME (section!=NULL); //TODO: actually it is possible that it si null we need to rethink how we handle this cases and do better there
781
782 return fileOffset - VAL32(section->PointerToRawData) + VAL32(section->VirtualAddress);
783 }
784 else return 0;
785}
786
787
788inline BOOL PEDecoder::IsStrongNameSigned() const
789{
790 CONTRACTL
791 {
792 INSTANCE_CHECK;
793 PRECONDITION(HasCorHeader());
794 NOTHROW;
795 GC_NOTRIGGER;
796 SUPPORTS_DAC;
797 SO_TOLERANT;
798 }
799 CONTRACTL_END;
800
801 return ((GetCorHeader()->Flags & VAL32(COMIMAGE_FLAGS_STRONGNAMESIGNED)) != 0);
802}
803
804
805inline BOOL PEDecoder::HasStrongNameSignature() const
806{
807 CONTRACTL
808 {
809 INSTANCE_CHECK;
810 PRECONDITION(HasCorHeader());
811 NOTHROW;
812 GC_NOTRIGGER;
813 SUPPORTS_DAC;
814 SO_TOLERANT;
815 }
816 CONTRACTL_END;
817
818 return (GetCorHeader()->StrongNameSignature.VirtualAddress != 0);
819}
820
821inline CHECK PEDecoder::CheckStrongNameSignature() const
822{
823 CONTRACT_CHECK
824 {
825 INSTANCE_CHECK;
826 PRECONDITION(CheckNTHeaders());
827 PRECONDITION(HasCorHeader());
828 PRECONDITION(HasStrongNameSignature());
829 NOTHROW;
830 GC_NOTRIGGER;
831 }
832 CONTRACT_CHECK_END;
833
834 return CheckDirectory(&GetCorHeader()->StrongNameSignature, IMAGE_SCN_MEM_WRITE, NULL_OK);
835}
836
837inline PTR_CVOID PEDecoder::GetStrongNameSignature(COUNT_T *pSize) const
838{
839 CONTRACT(PTR_CVOID)
840 {
841 INSTANCE_CHECK;
842 PRECONDITION(HasCorHeader());
843 PRECONDITION(HasStrongNameSignature());
844 PRECONDITION(CheckStrongNameSignature());
845 PRECONDITION(CheckPointer(pSize, NULL_OK));
846 NOTHROW;
847 GC_NOTRIGGER;
848 POSTCONDITION(CheckPointer(RETVAL));
849 }
850 CONTRACT_END;
851
852 IMAGE_DATA_DIRECTORY *pDir = &GetCorHeader()->StrongNameSignature;
853
854 if (pSize != NULL)
855 *pSize = VAL32(pDir->Size);
856
857 RETURN dac_cast<PTR_CVOID>(GetDirectoryData(pDir));
858}
859
860inline BOOL PEDecoder::HasTls() const
861{
862 CONTRACTL
863 {
864 INSTANCE_CHECK;
865 PRECONDITION(CheckNTHeaders());
866 NOTHROW;
867 GC_NOTRIGGER;
868 SO_TOLERANT;
869 }
870 CONTRACTL_END;
871
872 return HasDirectoryEntry(IMAGE_DIRECTORY_ENTRY_TLS);
873}
874
875inline CHECK PEDecoder::CheckTls() const
876{
877 CONTRACT_CHECK
878 {
879 INSTANCE_CHECK;
880 PRECONDITION(CheckNTHeaders());
881 NOTHROW;
882 GC_NOTRIGGER;
883 SO_TOLERANT;
884 }
885 CONTRACT_CHECK_END;
886
887 CHECK(CheckDirectoryEntry(IMAGE_DIRECTORY_ENTRY_TLS, 0, NULL_OK));
888
889 IMAGE_TLS_DIRECTORY *pTlsHeader = (IMAGE_TLS_DIRECTORY *) GetDirectoryEntryData(IMAGE_DIRECTORY_ENTRY_TLS);
890
891 CHECK(CheckUnderflow(VALPTR(pTlsHeader->EndAddressOfRawData), VALPTR(pTlsHeader->StartAddressOfRawData)));
892 CHECK(VALPTR(pTlsHeader->EndAddressOfRawData) - VALPTR(pTlsHeader->StartAddressOfRawData) <= COUNT_T_MAX);
893
894 CHECK(CheckInternalAddress(VALPTR(pTlsHeader->StartAddressOfRawData),
895 (COUNT_T) (VALPTR(pTlsHeader->EndAddressOfRawData) - VALPTR(pTlsHeader->StartAddressOfRawData))));
896
897 CHECK_OK;
898}
899
900inline PTR_VOID PEDecoder::GetTlsRange(COUNT_T * pSize) const
901{
902 CONTRACT(void *)
903 {
904 INSTANCE_CHECK;
905 PRECONDITION(CheckNTHeaders());
906 PRECONDITION(HasTls());
907 PRECONDITION(CheckTls());
908 NOTHROW;
909 GC_NOTRIGGER;
910 POSTCONDITION(CheckPointer(RETVAL));
911 }
912 CONTRACT_END;
913
914 IMAGE_TLS_DIRECTORY *pTlsHeader =
915 PTR_IMAGE_TLS_DIRECTORY(GetDirectoryEntryData(IMAGE_DIRECTORY_ENTRY_TLS));
916
917 if (pSize != 0)
918 *pSize = (COUNT_T) (VALPTR(pTlsHeader->EndAddressOfRawData) - VALPTR(pTlsHeader->StartAddressOfRawData));
919 PREFIX_ASSUME (pTlsHeader!=NULL);
920 RETURN PTR_VOID(GetInternalAddressData(pTlsHeader->StartAddressOfRawData));
921}
922
923inline UINT32 PEDecoder::GetTlsIndex() const
924{
925 CONTRACTL
926 {
927 INSTANCE_CHECK;
928 PRECONDITION(CheckNTHeaders());
929 PRECONDITION(HasTls());
930 PRECONDITION(CheckTls());
931 NOTHROW;
932 GC_NOTRIGGER;
933 }
934 CONTRACTL_END;
935
936 IMAGE_TLS_DIRECTORY *pTlsHeader = (IMAGE_TLS_DIRECTORY *) GetDirectoryEntryData(IMAGE_DIRECTORY_ENTRY_TLS);
937
938 return (UINT32)*PTR_UINT32(GetInternalAddressData((SIZE_T)VALPTR(pTlsHeader->AddressOfIndex)));
939}
940
941inline IMAGE_COR20_HEADER *PEDecoder::GetCorHeader() const
942{
943 CONTRACT(IMAGE_COR20_HEADER *)
944 {
945 INSTANCE_CHECK;
946 PRECONDITION(CheckNTHeaders());
947 PRECONDITION(HasCorHeader());
948 NOTHROW;
949 GC_NOTRIGGER;
950 SO_TOLERANT;
951 POSTCONDITION(CheckPointer(RETVAL));
952 CANNOT_TAKE_LOCK;
953 SUPPORTS_DAC;
954 }
955 CONTRACT_END;
956
957 if (m_pCorHeader == NULL)
958 const_cast<PEDecoder *>(this)->m_pCorHeader =
959 dac_cast<PTR_IMAGE_COR20_HEADER>(FindCorHeader());
960
961 RETURN m_pCorHeader;
962}
963
964inline BOOL PEDecoder::IsNativeMachineFormat() const
965{
966 if (!HasContents() || !HasNTHeaders() )
967 return FALSE;
968 _ASSERTE(m_pNTHeaders);
969 WORD expectedFormat = HasCorHeader() && (HasNativeHeader() || HasReadyToRunHeader()) ?
970 IMAGE_FILE_MACHINE_NATIVE_NI :
971 IMAGE_FILE_MACHINE_NATIVE;
972 //do not call GetNTHeaders as we do not want to bother with PE32->PE32+ conversion
973 return m_pNTHeaders->FileHeader.Machine==expectedFormat;
974}
975
976inline BOOL PEDecoder::IsI386() const
977{
978 if (!HasContents() || !HasNTHeaders() )
979 return FALSE;
980 _ASSERTE(m_pNTHeaders);
981 //do not call GetNTHeaders as we do not want to bother with PE32->PE32+ conversion
982 return m_pNTHeaders->FileHeader.Machine==IMAGE_FILE_MACHINE_I386;
983}
984
985inline CORCOMPILE_HEADER *PEDecoder::GetNativeHeader() const
986{
987 CONTRACT(CORCOMPILE_HEADER *)
988 {
989 INSTANCE_CHECK;
990 PRECONDITION(CheckNTHeaders());
991 PRECONDITION(HasCorHeader());
992 PRECONDITION(HasNativeHeader());
993 NOTHROW;
994 GC_NOTRIGGER;
995 POSTCONDITION(CheckPointer(RETVAL));
996 SO_TOLERANT;
997 SUPPORTS_DAC;
998 CANNOT_TAKE_LOCK;
999 SO_TOLERANT;
1000 }
1001 CONTRACT_END;
1002
1003 if (m_pNativeHeader == NULL)
1004 const_cast<PEDecoder *>(this)->m_pNativeHeader =
1005 dac_cast<PTR_CORCOMPILE_HEADER>(FindNativeHeader());
1006
1007 RETURN m_pNativeHeader;
1008}
1009
1010#ifdef FEATURE_PREJIT
1011inline const void * PEDecoder::GetNativePreferredBase() const
1012{
1013 CONTRACTL
1014 {
1015 INSTANCE_CHECK;
1016 PRECONDITION(CheckNativeHeader());
1017 NOTHROW;
1018 GC_NOTRIGGER;
1019 }
1020 CONTRACTL_END;
1021
1022 PREFIX_ASSUME (GetNativeHeader()!=NULL);
1023 return (const void *) GetNativeHeader()->ImageBase;
1024}
1025
1026inline BOOL PEDecoder::GetNativeILHasSecurityDirectory() const
1027{
1028 CONTRACTL
1029 {
1030 INSTANCE_CHECK;
1031 PRECONDITION(CheckNativeHeader());
1032 NOTHROW;
1033 GC_NOTRIGGER;
1034 }
1035 CONTRACTL_END;
1036
1037 PREFIX_ASSUME (GetNativeHeader()!=NULL);
1038 return (GetNativeHeader()->Flags & CORCOMPILE_HEADER_HAS_SECURITY_DIRECTORY) != 0;
1039}
1040
1041inline BOOL PEDecoder::GetNativeILIsIbcOptimized() const
1042{
1043 CONTRACTL
1044 {
1045 INSTANCE_CHECK;
1046 PRECONDITION(CheckNativeHeader());
1047 NOTHROW;
1048 GC_NOTRIGGER;
1049 }
1050 CONTRACTL_END;
1051
1052 PREFIX_ASSUME (GetNativeHeader()!=NULL);
1053 return (GetNativeHeader()->Flags & CORCOMPILE_HEADER_IS_IBC_OPTIMIZED) != 0;
1054}
1055
1056inline BOOL PEDecoder::GetNativeILHasReadyToRunHeader() const
1057{
1058 CONTRACTL
1059 {
1060 INSTANCE_CHECK;
1061 PRECONDITION(CheckNativeHeader());
1062 NOTHROW;
1063 GC_NOTRIGGER;
1064 }
1065 CONTRACTL_END;
1066
1067 PREFIX_ASSUME (GetNativeHeader()!=NULL);
1068 return (GetNativeHeader()->Flags & CORCOMPILE_HEADER_IS_READY_TO_RUN) != 0;
1069}
1070
1071inline BOOL PEDecoder::IsNativeILILOnly() const
1072{
1073 CONTRACTL
1074 {
1075 INSTANCE_CHECK;
1076 PRECONDITION(CheckNativeHeader());
1077 NOTHROW;
1078 GC_NOTRIGGER;
1079 SO_TOLERANT;
1080 CANNOT_TAKE_LOCK;
1081 SUPPORTS_DAC;
1082 }
1083 CONTRACTL_END;
1084
1085 PREFIX_ASSUME (GetNativeHeader()!=NULL);
1086 return((GetNativeHeader()->COR20Flags & VAL32(COMIMAGE_FLAGS_ILONLY)) != 0);
1087}
1088
1089inline BOOL PEDecoder::IsNativeILDll() const
1090{
1091 CONTRACTL
1092 {
1093 INSTANCE_CHECK;
1094 PRECONDITION(CheckNativeHeader());
1095 NOTHROW;
1096 GC_NOTRIGGER;
1097 }
1098 CONTRACTL_END;
1099
1100 PREFIX_ASSUME (GetNativeHeader()!=NULL);
1101 return((GetNativeHeader()->Characteristics & VAL16(IMAGE_FILE_DLL)) != 0);
1102}
1103
1104
1105inline void PEDecoder::GetNativeILPEKindAndMachine(DWORD* pdwKind, DWORD* pdwMachine) const
1106{
1107 CONTRACTL
1108 {
1109 INSTANCE_CHECK;
1110 PRECONDITION(CheckNativeHeader());
1111 NOTHROW;
1112 GC_NOTRIGGER;
1113 }
1114 CONTRACTL_END;
1115
1116 CORCOMPILE_HEADER * pNativeHeader = GetNativeHeader();
1117 PREFIX_ASSUME (pNativeHeader!=NULL);
1118
1119 if (pdwKind != NULL)
1120 *pdwKind = pNativeHeader->PEKind;
1121 if (pdwMachine != NULL)
1122 *pdwMachine = pNativeHeader->Machine;
1123}
1124
1125inline CORCOMPILE_DEPENDENCY * PEDecoder::GetNativeDependencies(COUNT_T *pCount) const
1126{
1127 CONTRACTL
1128 {
1129 INSTANCE_CHECK;
1130 PRECONDITION(CheckNativeHeader());
1131 NOTHROW;
1132 GC_NOTRIGGER;
1133 }
1134 CONTRACTL_END;
1135
1136 IMAGE_DATA_DIRECTORY *pDir = &GetNativeHeader()->Dependencies;
1137
1138 if (pCount != NULL)
1139 *pCount = VAL32(pDir->Size)/sizeof(CORCOMPILE_DEPENDENCY);
1140
1141 return (CORCOMPILE_DEPENDENCY *) GetDirectoryData(pDir);
1142}
1143
1144#endif // FEATURE_PREJIT
1145
1146// static
1147inline PTR_IMAGE_SECTION_HEADER PEDecoder::FindFirstSection(IMAGE_NT_HEADERS * pNTHeaders)
1148{
1149 LIMITED_METHOD_CONTRACT;
1150 SUPPORTS_DAC;
1151
1152 return dac_cast<PTR_IMAGE_SECTION_HEADER>(
1153 dac_cast<TADDR>(pNTHeaders) +
1154 FIELD_OFFSET(IMAGE_NT_HEADERS, OptionalHeader) +
1155 VAL16(pNTHeaders->FileHeader.SizeOfOptionalHeader));
1156}
1157
1158inline COUNT_T PEDecoder::GetNumberOfSections() const
1159{
1160 CONTRACTL
1161 {
1162 INSTANCE_CHECK;
1163 PRECONDITION(CheckNTHeaders());
1164 NOTHROW;
1165 GC_NOTRIGGER;
1166 SUPPORTS_DAC;
1167 }
1168 CONTRACTL_END;
1169
1170 return VAL16(FindNTHeaders()->FileHeader.NumberOfSections);
1171}
1172
1173
1174inline DWORD PEDecoder::GetImageIdentity() const
1175{
1176 WRAPPER_NO_CONTRACT;
1177 return GetTimeDateStamp() ^ GetCheckSum() ^ DWORD( GetVirtualSize() );
1178}
1179
1180
1181inline PTR_IMAGE_SECTION_HEADER PEDecoder::FindFirstSection() const
1182{
1183 CONTRACT(IMAGE_SECTION_HEADER *)
1184 {
1185 INSTANCE_CHECK;
1186 PRECONDITION(CheckNTHeaders());
1187 NOTHROW;
1188 GC_NOTRIGGER;
1189 POSTCONDITION(CheckPointer(RETVAL));
1190 SUPPORTS_DAC;
1191 }
1192 CONTRACT_END;
1193
1194 RETURN FindFirstSection(FindNTHeaders());
1195}
1196
1197inline IMAGE_NT_HEADERS *PEDecoder::FindNTHeaders() const
1198{
1199 CONTRACT(IMAGE_NT_HEADERS *)
1200 {
1201 INSTANCE_CHECK;
1202 NOTHROW;
1203 GC_NOTRIGGER;
1204 POSTCONDITION(CheckPointer(RETVAL));
1205 SO_TOLERANT;
1206 CANNOT_TAKE_LOCK;
1207 SUPPORTS_DAC;
1208 }
1209 CONTRACT_END;
1210
1211 RETURN PTR_IMAGE_NT_HEADERS(m_base + VAL32(PTR_IMAGE_DOS_HEADER(m_base)->e_lfanew));
1212}
1213
1214inline IMAGE_COR20_HEADER *PEDecoder::FindCorHeader() const
1215{
1216 CONTRACT(IMAGE_COR20_HEADER *)
1217 {
1218 INSTANCE_CHECK;
1219 PRECONDITION(HasCorHeader());
1220 NOTHROW;
1221 GC_NOTRIGGER;
1222 POSTCONDITION(CheckPointer(RETVAL));
1223 CANNOT_TAKE_LOCK;
1224 SO_TOLERANT;
1225 SUPPORTS_DAC;
1226 }
1227 CONTRACT_END;
1228
1229 const IMAGE_COR20_HEADER * pCor=PTR_IMAGE_COR20_HEADER(GetDirectoryEntryData(IMAGE_DIRECTORY_ENTRY_COMHEADER));
1230 RETURN ((IMAGE_COR20_HEADER*)pCor);
1231}
1232
1233inline CORCOMPILE_HEADER *PEDecoder::FindNativeHeader() const
1234{
1235 CONTRACT(CORCOMPILE_HEADER *)
1236 {
1237 INSTANCE_CHECK;
1238 PRECONDITION(HasNativeHeader());
1239 NOTHROW;
1240 GC_NOTRIGGER;
1241 POSTCONDITION(CheckPointer(RETVAL));
1242 SO_TOLERANT;
1243 CANNOT_TAKE_LOCK;
1244 SUPPORTS_DAC;
1245 }
1246 CONTRACT_END;
1247
1248 RETURN PTR_CORCOMPILE_HEADER(GetDirectoryData(&GetCorHeader()->ManagedNativeHeader));
1249}
1250
1251inline CHECK PEDecoder::CheckBounds(RVA rangeBase, COUNT_T rangeSize, RVA rva)
1252{
1253 WRAPPER_NO_CONTRACT;
1254 SUPPORTS_DAC;
1255 CHECK(CheckOverflow(rangeBase, rangeSize));
1256 CHECK(rva >= rangeBase);
1257 CHECK(rva <= rangeBase + rangeSize);
1258 CHECK_OK;
1259}
1260
1261inline CHECK PEDecoder::CheckBounds(RVA rangeBase, COUNT_T rangeSize, RVA rva, COUNT_T size)
1262{
1263 WRAPPER_NO_CONTRACT;
1264 SUPPORTS_DAC;
1265 CHECK(CheckOverflow(rangeBase, rangeSize));
1266 CHECK(CheckOverflow(rva, size));
1267 CHECK(rva >= rangeBase);
1268 CHECK(rva + size <= rangeBase + rangeSize);
1269 CHECK_OK;
1270}
1271
1272inline CHECK PEDecoder::CheckBounds(const void *rangeBase, COUNT_T rangeSize, const void *pointer)
1273{
1274 WRAPPER_NO_CONTRACT;
1275 SUPPORTS_DAC;
1276 CHECK(CheckOverflow(dac_cast<PTR_CVOID>(rangeBase), rangeSize));
1277 CHECK(dac_cast<TADDR>(pointer) >= dac_cast<TADDR>(rangeBase));
1278 CHECK(dac_cast<TADDR>(pointer) <= dac_cast<TADDR>(rangeBase) + rangeSize);
1279 CHECK_OK;
1280}
1281
1282inline CHECK PEDecoder::CheckBounds(PTR_CVOID rangeBase, COUNT_T rangeSize, PTR_CVOID pointer, COUNT_T size)
1283{
1284 WRAPPER_NO_CONTRACT;
1285 SUPPORTS_DAC;
1286 CHECK(CheckOverflow(rangeBase, rangeSize));
1287 CHECK(CheckOverflow(pointer, size));
1288 CHECK(dac_cast<TADDR>(pointer) >= dac_cast<TADDR>(rangeBase));
1289 CHECK(dac_cast<TADDR>(pointer) + size <= dac_cast<TADDR>(rangeBase) + rangeSize);
1290 CHECK_OK;
1291}
1292
1293inline void PEDecoder::GetPEKindAndMachine(DWORD * pdwPEKind, DWORD *pdwMachine)
1294{
1295 CONTRACTL
1296 {
1297 NOTHROW;
1298 GC_NOTRIGGER;
1299 }
1300 CONTRACTL_END;
1301
1302 DWORD dwKind=0,dwMachine=0;
1303 if(HasContents() && HasNTHeaders())
1304 {
1305 dwMachine = GetMachine();
1306
1307 BOOL fIsPE32Plus = !Has32BitNTHeaders();
1308
1309 if (fIsPE32Plus)
1310 dwKind |= (DWORD)pe32Plus;
1311
1312 if (HasCorHeader())
1313 {
1314 IMAGE_COR20_HEADER * pCorHdr = GetCorHeader();
1315 if(pCorHdr != NULL)
1316 {
1317 DWORD dwCorFlags = pCorHdr->Flags;
1318
1319 if (dwCorFlags & VAL32(COMIMAGE_FLAGS_ILONLY))
1320 {
1321 dwKind |= (DWORD)peILonly;
1322#ifdef _WIN64
1323 // compensate for shim promotion of PE32/ILONLY headers to PE32+ on WIN64
1324 if (fIsPE32Plus && (GetMachine() == IMAGE_FILE_MACHINE_I386))
1325 dwKind &= ~((DWORD)pe32Plus);
1326#endif
1327 }
1328
1329 if (COR_IS_32BIT_REQUIRED(dwCorFlags))
1330 dwKind |= (DWORD)pe32BitRequired;
1331 else if (COR_IS_32BIT_PREFERRED(dwCorFlags))
1332 dwKind |= (DWORD)pe32BitPreferred;
1333
1334 // compensate for MC++ peculiarity
1335 if(dwKind == 0)
1336 dwKind = (DWORD)pe32BitRequired;
1337 }
1338 else
1339 {
1340 dwKind |= (DWORD)pe32Unmanaged;
1341 }
1342
1343 if (HasReadyToRunHeader())
1344 {
1345 if (dwMachine == IMAGE_FILE_MACHINE_NATIVE_NI)
1346 {
1347 // Supply the original machine type to the assembly binder
1348 dwMachine = IMAGE_FILE_MACHINE_NATIVE;
1349 }
1350
1351 if ((GetReadyToRunHeader()->Flags & READYTORUN_FLAG_PLATFORM_NEUTRAL_SOURCE) != 0)
1352 {
1353 // Supply the original PEKind/Machine to the assembly binder to make the full assembly name look like the original
1354 dwKind = peILonly;
1355 dwMachine = IMAGE_FILE_MACHINE_I386;
1356 }
1357 }
1358 }
1359 else
1360 {
1361 dwKind |= (DWORD)pe32Unmanaged;
1362 }
1363 }
1364
1365 *pdwPEKind = dwKind;
1366 *pdwMachine = dwMachine;
1367}
1368
1369inline BOOL PEDecoder::IsPlatformNeutral()
1370{
1371 CONTRACTL
1372 {
1373 NOTHROW;
1374 GC_NOTRIGGER;
1375 }
1376 CONTRACTL_END;
1377
1378 DWORD dwKind, dwMachine;
1379 GetPEKindAndMachine(&dwKind, &dwMachine);
1380 return ((dwKind & (peILonly | pe32Plus | pe32BitRequired)) == peILonly) && (dwMachine == IMAGE_FILE_MACHINE_I386);
1381}
1382
1383inline BOOL PEDecoder::HasReadyToRunHeader() const
1384{
1385 CONTRACTL
1386 {
1387 INSTANCE_CHECK;
1388 NOTHROW;
1389 GC_NOTRIGGER;
1390 CANNOT_TAKE_LOCK;
1391 SO_TOLERANT;
1392 SUPPORTS_DAC;
1393 }
1394 CONTRACTL_END;
1395
1396 if (m_flags & FLAG_HAS_NO_READYTORUN_HEADER)
1397 return FALSE;
1398
1399 if (m_pReadyToRunHeader != NULL)
1400 return TRUE;
1401
1402 return FindReadyToRunHeader() != NULL;
1403}
1404
1405inline READYTORUN_HEADER * PEDecoder::GetReadyToRunHeader() const
1406{
1407 CONTRACT(READYTORUN_HEADER *)
1408 {
1409 INSTANCE_CHECK;
1410 PRECONDITION(CheckNTHeaders());
1411 PRECONDITION(HasCorHeader());
1412 PRECONDITION(HasReadyToRunHeader());
1413 NOTHROW;
1414 GC_NOTRIGGER;
1415 POSTCONDITION(CheckPointer(RETVAL));
1416 SO_TOLERANT;
1417 SUPPORTS_DAC;
1418 CANNOT_TAKE_LOCK;
1419 SO_TOLERANT;
1420 }
1421 CONTRACT_END;
1422
1423 if (m_pReadyToRunHeader != NULL)
1424 RETURN m_pReadyToRunHeader;
1425
1426 RETURN FindReadyToRunHeader();
1427}
1428
1429#endif // _PEDECODER_INL_
1430