Merge pull request #3896 from adityamandaleeka/configvalues4
[platform/upstream/coreclr.git] / src / ildasm / ceeload.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 // CEELOAD reads in the PE file format using LoadLibrary
7 // ===========================================================================
8 #include "ildasmpch.h"
9
10 #include "ceeload.h"
11 #include <corhdr.h>
12 #include <corimage.h>
13 #include "util.hpp"
14 #include "pedecoder.h"
15
16 /*************************************************************************************/
17 // Constructor and destructor!
18 /*************************************************************************************/
19 PELoader::PELoader()
20 {
21     m_hFile = NULL;
22     m_hMod = NULL;
23     m_hMapFile = NULL;
24     m_pNT64 = NULL;
25     m_bIsPE32 = FALSE;
26     m_FileSize = m_FileSizeAligned = 0;
27 }
28
29 PELoader::~PELoader()
30 {
31
32     m_hMod = NULL;
33     m_pNT64 = NULL;
34     // If we have an hFile then we opened this file ourselves!
35     // If we do not then this file was loaded by the OS and the OS will
36     // close it for us.
37     if (m_hFile)
38         this->close();
39 }
40
41 /*************************************************************************************/
42 /*************************************************************************************/
43 void PELoader::close()
44 {
45
46     // _ASSERTE(m_hFile != NULL);
47     if (m_hFile)
48     {
49         if (m_hMod)
50             UnmapViewOfFile((void*)m_hMod);
51         if (m_hMapFile)
52             CloseHandle(m_hMapFile);
53         CloseHandle(m_hFile);
54
55         m_hMod = NULL;
56         m_hMapFile = NULL;
57         m_hFile = NULL;
58         m_FileSize = m_FileSizeAligned = 0;
59     }
60 }
61
62
63 BOOL PELoader::open(LPCSTR moduleName)
64 {
65     HMODULE newhMod = NULL;
66     DWORD dwFileSizeLow;
67
68     _ASSERTE(moduleName);
69     if (!moduleName)
70         return FALSE;
71
72
73     m_hFile = CreateFileA(moduleName, GENERIC_READ, FILE_SHARE_READ,
74                          0, OPEN_EXISTING, 0, 0);
75     if (m_hFile == INVALID_HANDLE_VALUE)
76         return FALSE;
77
78     dwFileSizeLow = GetFileSize( m_hFile, NULL); 
79     if (dwFileSizeLow == INVALID_FILE_SIZE)
80         return FALSE;
81     m_FileSize = dwFileSizeLow;
82
83     m_hMapFile = WszCreateFileMapping(m_hFile, NULL, PAGE_READONLY, 0, 0, NULL);
84     if (m_hMapFile == NULL)
85         return FALSE;
86
87     newhMod = (HMODULE) MapViewOfFile(m_hMapFile, FILE_MAP_READ, 0, 0, 0);
88     if (newhMod == NULL)
89         return FALSE;
90    return open(newhMod);
91 }
92
93 BOOL PELoader::open(const WCHAR* moduleName)
94 {
95     HMODULE newhMod = NULL;
96     DWORD dwFileSizeLow;
97
98     _ASSERTE(moduleName);
99     if (!moduleName)
100         return FALSE;
101
102     m_hFile = WszCreateFile(moduleName, GENERIC_READ, FILE_SHARE_READ,
103                          0, OPEN_EXISTING, 0, 0);
104     if (m_hFile == INVALID_HANDLE_VALUE)
105         return FALSE;
106
107     dwFileSizeLow = GetFileSize( m_hFile, NULL); 
108     if (dwFileSizeLow == INVALID_FILE_SIZE)
109         return FALSE;
110     m_FileSize = dwFileSizeLow;
111
112     m_hMapFile = WszCreateFileMapping(m_hFile, NULL, PAGE_READONLY, 0, 0, NULL);
113     if (m_hMapFile == NULL)
114         return FALSE;
115
116     newhMod = (HMODULE) MapViewOfFile(m_hMapFile, FILE_MAP_READ, 0, 0, 0);
117     if (newhMod == NULL)
118         return FALSE;
119    return open(newhMod);
120 }
121
122
123 /*************************************************************************************/
124 BOOL PELoader::open(HMODULE hMod)
125 {
126     IMAGE_DOS_HEADER * pdosHeader;
127     
128     // get the dos header...
129     m_hMod = hMod;
130     pdosHeader = (IMAGE_DOS_HEADER*) hMod;
131     // If this is not a PE32+ image
132     if (pdosHeader->e_magic == VAL16(IMAGE_DOS_SIGNATURE) &&
133         0 < VAL32(pdosHeader->e_lfanew) && VAL32(pdosHeader->e_lfanew) < 0xFF0)   // has to start on first page
134     {
135         size_t fileAlignment;
136
137         m_pNT32 = (IMAGE_NT_HEADERS32*) ((BYTE *)m_hMod + VAL32(pdosHeader->e_lfanew));
138
139         m_bIsPE32 = (m_pNT32->OptionalHeader.Magic == VAL16(IMAGE_NT_OPTIONAL_HDR32_MAGIC));
140
141         if (m_bIsPE32)
142         {
143             if ((m_pNT32->Signature != VAL32(IMAGE_NT_SIGNATURE)) ||
144                 (m_pNT32->FileHeader.SizeOfOptionalHeader != VAL16(sizeof(IMAGE_OPTIONAL_HEADER32))))
145             {
146                 // Make this appear uninitalized because for some reason this file is toasted.
147                 m_pNT32 = NULL;
148                 m_hMod = NULL;
149                 return FALSE;
150             }
151             fileAlignment = VAL32(m_pNT32->OptionalHeader.FileAlignment)-1;
152         }
153         else //For now assume not i386 is IA64
154         {
155             if ((m_pNT64->Signature != VAL32(IMAGE_NT_SIGNATURE)) ||
156                 (m_pNT64->FileHeader.SizeOfOptionalHeader != VAL16(sizeof(IMAGE_OPTIONAL_HEADER64))))
157             {
158                 // Make this appear uninitalized because for some reason this file is toasted.
159                 m_pNT64 = NULL;
160                 m_hMod = NULL;
161                 return FALSE;
162             }
163             fileAlignment = VAL32(m_pNT64->OptionalHeader.FileAlignment)-1;
164         }
165         m_FileSizeAligned = (m_FileSize + fileAlignment)&(~fileAlignment);
166     }
167     else
168     {
169         // Make this appear uninitalized because for some reason this file is toasted.
170         m_hMod = NULL;
171         return FALSE;
172     }
173     return TRUE;
174 }
175
176 /*************************************************************************************/
177 void PELoader::dump()
178 {
179 }
180
181 /*************************************************************************************/
182 BOOL PELoader::getCOMHeader(IMAGE_COR20_HEADER **ppCorHeader)
183 {
184     PIMAGE_SECTION_HEADER   pSectionHeader;
185
186     if (m_bIsPE32)
187     {
188         PIMAGE_NT_HEADERS32     pImageHeader;
189         // Get the image header from the image, then get the directory location
190         // of the COM+ header which may or may not be filled out.
191         pImageHeader = (PIMAGE_NT_HEADERS32)Cor_RtlImageNtHeader(m_hMod, (ULONG) m_FileSize);
192         PREFIX_ASSUME(pImageHeader != NULL);
193         pSectionHeader = (PIMAGE_SECTION_HEADER) Cor_RtlImageRvaToVa32(pImageHeader, (PBYTE)m_hMod,
194             VAL32(pImageHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COMHEADER].VirtualAddress),
195             (DWORD)m_FileSizeAligned /* FileLength */);
196     }
197     else
198     {
199         PIMAGE_NT_HEADERS64     pImageHeader;
200
201         // Get the image header from the image, then get the directory location
202         // of the COM+ header which may or may not be filled out.
203         pImageHeader = (PIMAGE_NT_HEADERS64)Cor_RtlImageNtHeader(m_hMod, (ULONG) m_FileSize);
204         PREFIX_ASSUME(pImageHeader != NULL);
205         pSectionHeader = (PIMAGE_SECTION_HEADER) Cor_RtlImageRvaToVa64(pImageHeader, (PBYTE)m_hMod,
206             VAL32(pImageHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COMHEADER].VirtualAddress),
207             (DWORD)m_FileSizeAligned /* FileLength */);
208     }
209
210     // If the section header exists, then return ok and the address.
211     if (pSectionHeader)
212     {
213         *ppCorHeader = (IMAGE_COR20_HEADER *) pSectionHeader;
214         return TRUE;
215     }
216     // If there is no COM+ Data in this image, return false.
217     else
218         return FALSE;
219 }
220
221 /*************************************************************************************/
222 BOOL PELoader::getVAforRVA(DWORD rva,void **ppva)
223 {
224     PIMAGE_SECTION_HEADER   pSectionHeader;
225
226     if (m_bIsPE32)
227     {
228         // Get the image header from the image, then get the directory location
229         // of the COM+ header which may or may not be filled out.
230         PIMAGE_NT_HEADERS32     pImageHeader;
231         pImageHeader = (PIMAGE_NT_HEADERS32) Cor_RtlImageNtHeader(m_hMod, (ULONG) m_FileSize);
232         PREFIX_ASSUME(pImageHeader != NULL);
233         pSectionHeader = (PIMAGE_SECTION_HEADER) Cor_RtlImageRvaToVa32(pImageHeader, (PBYTE)m_hMod,
234             rva, (DWORD)m_FileSizeAligned /* FileLength */);
235     }
236     else
237     {
238         PIMAGE_NT_HEADERS64     pImageHeader;
239         pImageHeader = (PIMAGE_NT_HEADERS64) Cor_RtlImageNtHeader(m_hMod, (ULONG) m_FileSize);
240         PREFIX_ASSUME(pImageHeader != NULL);
241         pSectionHeader = (PIMAGE_SECTION_HEADER) Cor_RtlImageRvaToVa64(pImageHeader, (PBYTE)m_hMod,
242             rva, (DWORD)m_FileSizeAligned /* FileLength */);
243     }
244
245     // If the section header exists, then return ok and the address.
246     if (pSectionHeader)
247     {
248         *ppva = pSectionHeader;
249         return TRUE;
250     }
251     // If there is no COM+ Data in this image, return false.
252     else
253         return FALSE;
254 }
255
256 void SectionInfo::Init(PELoader *pPELoader, IMAGE_DATA_DIRECTORY *dir)
257 {
258     _ASSERTE(dir);
259     m_dwSectionOffset = VAL32(dir->VirtualAddress);
260     if (m_dwSectionOffset != 0)
261         m_pSection = pPELoader->base() + m_dwSectionOffset;
262     else
263         m_pSection = 0;
264     m_dwSectionSize = VAL32(dir->Size);
265 }
266