[Tizen] Unify dnetmemoryenumlib terms to match the codebase (#291)
[platform/upstream/coreclr.git] / src / utilcode / corimage.cpp
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 // 
6
7 /*============================================================
8 **
9 ** CorImage.cpp
10 **
11 ** IMAGEHLP routines so we can avoid early binding to that DLL.
12 **
13 ===========================================================*/
14
15 #include "stdafx.h"
16 #include "contract.h"
17 #include <daccess.h>
18 #include "corimage.h"
19 #include "safemath.h"
20
21 #define RTL_MEG                   (1024UL * 1024UL)
22 #define RTLP_IMAGE_MAX_DOS_HEADER ( 256UL * RTL_MEG)
23
24 // IMAGE_FIRST_SECTION doesn't need 32/64 versions since the file header is
25 // the same either way.
26
27 #define PTR_IMAGE_FIRST_SECTION( ntheader )                            \
28    PTR_IMAGE_SECTION_HEADER                                            \
29     (dac_cast<TADDR>(ntheader) +                                       \
30      FIELD_OFFSET( IMAGE_NT_HEADERS, OptionalHeader ) +                \
31      VAL16((ntheader)->FileHeader.SizeOfOptionalHeader)                \
32     )
33
34 #ifndef DACCESS_COMPILE
35
36 IMAGE_NT_HEADERS *Cor_RtlImageNtHeader(VOID *pvBase, ULONG FileLength)
37 {
38     LIMITED_METHOD_CONTRACT;
39     IMAGE_NT_HEADERS *pNtHeaders = NULL;
40     if (pvBase && (pvBase != (VOID*)-1)) {
41         struct Param
42         {
43             IMAGE_DOS_HEADER *pDos;
44             ULONG FileLength;
45             IMAGE_NT_HEADERS *pNtHeaders;
46         } param;
47         param.pDos = (IMAGE_DOS_HEADER*)pvBase;
48         param.FileLength = FileLength;
49         param.pNtHeaders = pNtHeaders;
50
51         PAL_TRY(Param *, pParam, &param) {
52             if (   (pParam->pDos->e_magic == VAL16(IMAGE_DOS_SIGNATURE)) 
53                 && ((DWORD)VAL32(pParam->pDos->e_lfanew) < RTLP_IMAGE_MAX_DOS_HEADER) 
54                 && ovadd_lt((DWORD)VAL32(pParam->pDos->e_lfanew), sizeof(IMAGE_FILE_HEADER) + sizeof(DWORD), pParam->FileLength)) {
55                 pParam->pNtHeaders = (IMAGE_NT_HEADERS*)((BYTE*)pParam->pDos + VAL32(pParam->pDos->e_lfanew));
56                 if (pParam->pNtHeaders->Signature != VAL32(IMAGE_NT_SIGNATURE))
57                     pParam->pNtHeaders = NULL;
58             }
59         }
60         PAL_EXCEPT(EXCEPTION_EXECUTE_HANDLER) {
61             param.pNtHeaders = NULL;
62         }
63         PAL_ENDTRY
64
65         pNtHeaders = param.pNtHeaders;
66     }
67     return pNtHeaders;
68 }
69
70 #endif // #ifndef DACCESS_COMPILE
71
72 EXTERN_C PIMAGE_SECTION_HEADER
73 Cor_RtlImageRvaToSection32(PTR_IMAGE_NT_HEADERS32 NtHeaders,
74                            ULONG Rva,
75                            ULONG FileLength)
76 {
77     LIMITED_METHOD_CONTRACT;
78     ULONG i;
79     PTR_IMAGE_SECTION_HEADER NtSection;
80
81     NtSection = PTR_IMAGE_FIRST_SECTION( NtHeaders );
82     for (i=0; i<NtHeaders->FileHeader.NumberOfSections; i++) {
83         if (FileLength &&
84             (((VAL32(NtSection->PointerToRawData) > FileLength)) ||
85             (VAL32(NtSection->SizeOfRawData) > FileLength - VAL32(NtSection->PointerToRawData))))
86             return NULL;
87         if (Rva >= VAL32(NtSection->VirtualAddress) &&
88             Rva < VAL32(NtSection->VirtualAddress) + VAL32(NtSection->SizeOfRawData))
89             return NtSection;
90         
91         ++NtSection;
92     }
93
94     return NULL;
95 }
96
97 EXTERN_C PIMAGE_SECTION_HEADER
98 Cor_RtlImageRvaToSection64(PTR_IMAGE_NT_HEADERS64 NtHeaders,
99                            ULONG Rva,
100                            ULONG FileLength)
101 {
102     LIMITED_METHOD_CONTRACT;
103     ULONG i;
104     PTR_IMAGE_SECTION_HEADER NtSection;
105
106     NtSection = PTR_IMAGE_FIRST_SECTION( NtHeaders );
107     for (i=0; i<VAL16(NtHeaders->FileHeader.NumberOfSections); i++) {
108         if (FileLength &&
109             (((VAL32(NtSection->PointerToRawData) > FileLength)) ||
110             (VAL32(NtSection->SizeOfRawData) > FileLength - VAL32(NtSection->PointerToRawData))))
111             return NULL;
112         if (Rva >= VAL32(NtSection->VirtualAddress) &&
113             Rva < VAL32(NtSection->VirtualAddress) + VAL32(NtSection->SizeOfRawData))
114             return NtSection;
115         
116         ++NtSection;
117     }
118
119     return NULL;
120 }
121
122 EXTERN_C PIMAGE_SECTION_HEADER
123 Cor_RtlImageRvaToSection(PTR_IMAGE_NT_HEADERS NtHeaders,
124                          ULONG Rva,
125                          ULONG FileLength)
126 {
127     LIMITED_METHOD_CONTRACT;
128     if (NtHeaders->OptionalHeader.Magic == VAL16(IMAGE_NT_OPTIONAL_HDR32_MAGIC))
129         return Cor_RtlImageRvaToSection32((PTR_IMAGE_NT_HEADERS32)NtHeaders,
130                                           Rva, FileLength);
131     else if(NtHeaders->OptionalHeader.Magic == VAL16(IMAGE_NT_OPTIONAL_HDR64_MAGIC))
132         return Cor_RtlImageRvaToSection64((PTR_IMAGE_NT_HEADERS64)NtHeaders,
133                                           Rva, FileLength);
134     else {
135         _ASSERTE(!"Invalid File Type");
136         return NULL;
137     }
138 }
139
140 EXTERN_C PBYTE Cor_RtlImageRvaToVa32(PTR_IMAGE_NT_HEADERS32 NtHeaders,
141                                      PBYTE Base,
142                                      ULONG Rva,
143                                      ULONG FileLength)
144 {
145     LIMITED_METHOD_CONTRACT;
146     PIMAGE_SECTION_HEADER NtSection =
147         Cor_RtlImageRvaToSection32(NtHeaders,
148                                    Rva,
149                                    FileLength);
150
151     if (NtSection != NULL)
152         return (Base +
153                 (Rva - VAL32(NtSection->VirtualAddress)) +
154                 VAL32(NtSection->PointerToRawData));
155     else
156         return NULL;
157 }
158
159 EXTERN_C PBYTE Cor_RtlImageRvaToVa64(PTR_IMAGE_NT_HEADERS64 NtHeaders,
160                                      PBYTE Base,
161                                      ULONG Rva,
162                                      ULONG FileLength)
163 {
164     LIMITED_METHOD_CONTRACT;
165     PIMAGE_SECTION_HEADER NtSection =
166         Cor_RtlImageRvaToSection64(NtHeaders,
167                                    Rva,
168                                    FileLength);
169
170     if (NtSection != NULL)
171         return (Base +
172                 (Rva - VAL32(NtSection->VirtualAddress)) +
173                 VAL32(NtSection->PointerToRawData));
174     else
175         return NULL;
176 }
177
178 EXTERN_C PBYTE Cor_RtlImageRvaToVa(PTR_IMAGE_NT_HEADERS NtHeaders,
179                                    PBYTE Base,
180                                    ULONG Rva,
181                                    ULONG FileLength)
182 {
183     LIMITED_METHOD_CONTRACT;
184     if (NtHeaders->OptionalHeader.Magic == VAL16(IMAGE_NT_OPTIONAL_HDR32_MAGIC))
185         return Cor_RtlImageRvaToVa32((PTR_IMAGE_NT_HEADERS32)NtHeaders,
186                                      Base, Rva, FileLength);
187     else if(NtHeaders->OptionalHeader.Magic == VAL16(IMAGE_NT_OPTIONAL_HDR64_MAGIC))
188         return Cor_RtlImageRvaToVa64((PTR_IMAGE_NT_HEADERS64)NtHeaders,
189                                      Base, Rva, FileLength);
190     else {
191         _ASSERTE(!"Invalid File Type");
192         return NULL;
193     }
194 }
195
196 EXTERN_C PBYTE Cor_RtlImageDirToVa(PTR_IMAGE_NT_HEADERS NtHeaders,
197                                    PBYTE Base,
198                                    UINT  DirIndex,
199                                    ULONG FileLength)
200 {
201     LIMITED_METHOD_CONTRACT;
202     if (NtHeaders->OptionalHeader.Magic == VAL16(IMAGE_NT_OPTIONAL_HDR32_MAGIC))
203         return Cor_RtlImageRvaToVa32((PTR_IMAGE_NT_HEADERS32)NtHeaders, Base, 
204                                      VAL32(((PTR_IMAGE_NT_HEADERS32)NtHeaders)->OptionalHeader.DataDirectory[DirIndex].VirtualAddress), 
205                                      FileLength);
206     else if(NtHeaders->OptionalHeader.Magic == VAL16(IMAGE_NT_OPTIONAL_HDR64_MAGIC))
207         return Cor_RtlImageRvaToVa64((PTR_IMAGE_NT_HEADERS64)NtHeaders, Base, 
208                                      VAL32(((PTR_IMAGE_NT_HEADERS64)NtHeaders)->OptionalHeader.DataDirectory[DirIndex].VirtualAddress), 
209                                      FileLength);
210     else {
211         _ASSERTE(!"Invalid File Type");
212         return NULL;
213     }
214 }
215
216 EXTERN_C PIMAGE_SECTION_HEADER
217 Cor_RtlImageRvaRangeToSection(PTR_IMAGE_NT_HEADERS NtHeaders,
218                               ULONG Rva,
219                               ULONG Range,
220                               ULONG FileLength)
221 {
222     LIMITED_METHOD_CONTRACT;
223     ULONG i;
224     PTR_IMAGE_SECTION_HEADER NtSection;
225
226     if (!Range)
227         return Cor_RtlImageRvaToSection(NtHeaders, Rva, FileLength);
228
229     NtSection = PTR_IMAGE_FIRST_SECTION( NtHeaders );
230     for (i=0; i<VAL16(NtHeaders->FileHeader.NumberOfSections); i++) {
231         if (FileLength &&
232             ((VAL32(NtSection->PointerToRawData) > FileLength) ||
233              (VAL32(NtSection->SizeOfRawData) > FileLength - VAL32(NtSection->PointerToRawData))))
234             return NULL;
235         if (Rva >= VAL32(NtSection->VirtualAddress) &&
236             Rva + Range <= VAL32(NtSection->VirtualAddress) + VAL32(NtSection->SizeOfRawData))
237             return NtSection;
238         
239         ++NtSection;
240     }
241
242     return NULL;
243 }
244
245 EXTERN_C DWORD Cor_RtlImageRvaToOffset(PTR_IMAGE_NT_HEADERS NtHeaders,
246                                        ULONG Rva,
247                                        ULONG FileLength)
248 {
249     LIMITED_METHOD_CONTRACT;
250     PIMAGE_SECTION_HEADER NtSection =
251         Cor_RtlImageRvaToSection(NtHeaders,
252                                  Rva,
253                                  FileLength);
254
255     if (NtSection)
256         return ((Rva - VAL32(NtSection->VirtualAddress)) +
257                 VAL32(NtSection->PointerToRawData));
258     else
259         return NULL;
260 }