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 | |
18 | inline 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 |
37 | inline PEDecoder::PEDecoder() |
38 | { |
39 | LIMITED_METHOD_CONTRACT; |
40 | } |
41 | #endif // #ifndef DACCESS_COMPILE |
42 | |
43 | inline PTR_VOID PEDecoder::GetBase() const |
44 | { |
45 | LIMITED_METHOD_CONTRACT; |
46 | SUPPORTS_DAC; |
47 | |
48 | return PTR_VOID(m_base); |
49 | } |
50 | |
51 | inline BOOL PEDecoder::IsMapped() const |
52 | { |
53 | LIMITED_METHOD_CONTRACT; |
54 | SUPPORTS_DAC; |
55 | |
56 | return (m_flags & FLAG_MAPPED) != 0; |
57 | } |
58 | |
59 | inline BOOL PEDecoder::IsRelocated() const |
60 | { |
61 | LIMITED_METHOD_CONTRACT; |
62 | |
63 | return (m_flags & FLAG_RELOCATED) != 0; |
64 | } |
65 | |
66 | inline void PEDecoder::SetRelocated() |
67 | { |
68 | m_flags |= FLAG_RELOCATED; |
69 | } |
70 | |
71 | inline BOOL PEDecoder::IsFlat() const |
72 | { |
73 | LIMITED_METHOD_CONTRACT; |
74 | |
75 | return HasContents() && !IsMapped(); |
76 | } |
77 | |
78 | inline BOOL PEDecoder::HasContents() const |
79 | { |
80 | LIMITED_METHOD_CONTRACT; |
81 | SUPPORTS_DAC; |
82 | |
83 | return (m_flags & FLAG_CONTENTS) != 0; |
84 | } |
85 | |
86 | inline COUNT_T PEDecoder::GetSize() const |
87 | { |
88 | LIMITED_METHOD_DAC_CONTRACT; |
89 | |
90 | return m_size; |
91 | } |
92 | |
93 | inline 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?? |
133 | inline 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 | |
153 | inline 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 | |
172 | inline 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 | |
201 | inline 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 | |
221 | inline IMAGE_NT_HEADERS32 *PEDecoder::() const |
222 | { |
223 | WRAPPER_NO_CONTRACT; |
224 | SUPPORTS_DAC; |
225 | return dac_cast<PTR_IMAGE_NT_HEADERS32>(FindNTHeaders()); |
226 | } |
227 | |
228 | inline IMAGE_NT_HEADERS64 *PEDecoder::() const |
229 | { |
230 | WRAPPER_NO_CONTRACT; |
231 | SUPPORTS_DAC; |
232 | return dac_cast<PTR_IMAGE_NT_HEADERS64>(FindNTHeaders()); |
233 | } |
234 | |
235 | inline BOOL PEDecoder::() 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 | |
253 | inline const void *PEDecoder::(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 | |
272 | inline 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 | |
287 | inline 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 | |
301 | inline 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 | |
320 | inline 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 | |
337 | inline 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 | |
354 | inline 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 | |
370 | inline 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 | |
384 | inline 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 | |
399 | inline 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 | |
414 | inline 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 | |
429 | inline 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 | |
443 | inline 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 | |
457 | inline 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 | |
475 | inline 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 | |
493 | inline 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 | |
511 | inline 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 | |
528 | inline 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 | |
545 | inline 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 | |
562 | inline 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 | |
579 | inline 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 | |
598 | inline 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 | |
625 | inline 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 | |
650 | inline 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 | |
669 | inline 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 | |
691 | inline 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 | |
708 | inline BOOL PEDecoder::() 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 | |
724 | inline 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 | |
741 | inline 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 | |
765 | inline 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 | |
788 | inline 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 | |
805 | inline 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 | |
821 | inline 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 | |
837 | inline 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 | |
860 | inline 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 | |
875 | inline 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 * = (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 | |
900 | inline 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 * = |
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 | |
923 | inline 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 * = (IMAGE_TLS_DIRECTORY *) GetDirectoryEntryData(IMAGE_DIRECTORY_ENTRY_TLS); |
937 | |
938 | return (UINT32)*PTR_UINT32(GetInternalAddressData((SIZE_T)VALPTR(pTlsHeader->AddressOfIndex))); |
939 | } |
940 | |
941 | inline IMAGE_COR20_HEADER *PEDecoder::() 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 | |
964 | inline 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 | |
976 | inline 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 | |
985 | inline CORCOMPILE_HEADER *PEDecoder::() 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 |
1011 | inline 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 | |
1026 | inline 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 | |
1041 | inline 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 | |
1056 | inline BOOL PEDecoder::() 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 | |
1071 | inline 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 | |
1089 | inline 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 | |
1105 | inline 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 * = 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 | |
1125 | inline 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 |
1147 | inline PTR_IMAGE_SECTION_HEADER PEDecoder::(IMAGE_NT_HEADERS * ) |
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 | |
1158 | inline 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 | |
1174 | inline DWORD PEDecoder::GetImageIdentity() const |
1175 | { |
1176 | WRAPPER_NO_CONTRACT; |
1177 | return GetTimeDateStamp() ^ GetCheckSum() ^ DWORD( GetVirtualSize() ); |
1178 | } |
1179 | |
1180 | |
1181 | inline 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 | |
1197 | inline IMAGE_NT_HEADERS *PEDecoder::() 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 | |
1214 | inline IMAGE_COR20_HEADER *PEDecoder::() 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 | |
1233 | inline CORCOMPILE_HEADER *PEDecoder::() 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 | |
1251 | inline 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 | |
1261 | inline 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 | |
1272 | inline 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 | |
1282 | inline 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 | |
1293 | inline 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 | |
1369 | inline 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 | |
1383 | inline BOOL PEDecoder::() 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 | |
1405 | inline READYTORUN_HEADER * PEDecoder::() 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 | |