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 | // File: CeeFileGenWriter.h |
6 | // |
7 | // =========================================================================== |
8 | |
9 | #ifndef _CEEFILEGENWRITER_H_ |
10 | #define _CEEFILEGENWRITER_H_ |
11 | // |
12 | |
13 | // CeeFileGenWriter contains all the code necessary to actually write an exe |
14 | // while CCeeGen contains everything else. This lets CeeGen.exe and the VM |
15 | // share more code without forcing the VM to carry the extra code to write an |
16 | // exe. |
17 | #include <windef.h> |
18 | #include "ceegen.h" |
19 | #include "iceefilegen.h" |
20 | |
21 | class PEWriter; |
22 | class CeeFileGenWriter; |
23 | |
24 | // default setting for PE file |
25 | const UINT32 CEE_IMAGE_BASE_32 = 0x00400000; |
26 | const UINT64 CEE_IMAGE_BASE_64 = UI64(0x0000000140000000); |
27 | const int CEE_IMAGE_SUBSYSTEM_MAJOR_VERSION = 4; |
28 | const int CEE_IMAGE_SUBSYSTEM_MINOR_VERSION = 0; |
29 | |
30 | class CeeFileGenWriter : public CCeeGen |
31 | { |
32 | mdToken m_entryPoint; // token for entry point |
33 | DWORD m_comImageFlags; |
34 | |
35 | LPWSTR m_outputFileName; |
36 | LPWSTR m_resourceFileName; |
37 | LPWSTR m_libraryName; |
38 | GUID m_libraryGuid; |
39 | bool m_dllSwitch; |
40 | |
41 | ULONG m_iatOffset; |
42 | DWORD m_dwMacroDefinitionRVA; |
43 | DWORD m_dwMacroDefinitionSize; |
44 | |
45 | DWORD m_dwManifestRVA; |
46 | DWORD m_dwManifestSize; |
47 | |
48 | DWORD m_dwStrongNameRVA; |
49 | DWORD m_dwStrongNameSize; |
50 | |
51 | DWORD m_dwVTableRVA; |
52 | DWORD m_dwVTableSize; |
53 | |
54 | bool m_linked; |
55 | bool m_fixed; |
56 | |
57 | HRESULT checkForErrors(); |
58 | |
59 | struct IDataDllInfo { |
60 | const char *m_name; |
61 | int m_numMethods; |
62 | const char **m_methodName; |
63 | int m_iltOffset; |
64 | int m_ibnOffset; |
65 | int m_iatOffset; |
66 | int m_nameOffset; |
67 | } *m_iDataDlls; |
68 | int m_dllCount; |
69 | |
70 | CeeSection *m_iDataSectionIAT; |
71 | int m_iDataOffsetIAT; |
72 | char *m_iDataIAT; |
73 | |
74 | #ifdef EMIT_FIXUPS |
75 | |
76 | CeeSection * m_sectionFixups; |
77 | IMAGE_DEBUG_DIRECTORY * m_pDebugDir; |
78 | bool m_fFixupsUpdated; |
79 | bool m_fEmitFixups; |
80 | |
81 | #endif |
82 | |
83 | HRESULT allocateIAT(); |
84 | public: |
85 | // Create with one of these two methods, not operator new |
86 | static HRESULT CreateNewInstance(CCeeGen *pCeeFileGenFrom, CeeFileGenWriter* & pGenWriter, |
87 | DWORD createFlags = ICEE_CREATE_FILE_PURE_IL); |
88 | // See ICeeFileGen.h for the definition of the bits used in createFlags |
89 | static HRESULT CreateNewInstanceEx(CCeeGen *pCeeFileGenFrom, CeeFileGenWriter* & pGenWriter, |
90 | DWORD createFlags, LPCWSTR seedFileName = NULL); |
91 | |
92 | virtual HRESULT Cleanup(); |
93 | |
94 | PEWriter &getPEWriter(); |
95 | |
96 | HRESULT link(); // Layout the sections and assign their starting addresses |
97 | HRESULT fixup(); // Apply relocations to any pointer data. Also generate PE base relocs |
98 | HRESULT generateImage(void **ppImage); |
99 | |
100 | HRESULT setImageBase(size_t imageBase); |
101 | HRESULT setImageBase64(ULONGLONG imageBase); |
102 | HRESULT setFileAlignment(ULONG fileAlignment); |
103 | HRESULT setSubsystem(DWORD subsystem, DWORD major, DWORD minor); |
104 | |
105 | HRESULT getMethodRVA(ULONG codeOffset, ULONG *codeRVA); |
106 | |
107 | HRESULT setEntryPoint(mdMethodDef method); |
108 | mdMethodDef getEntryPoint(); |
109 | |
110 | HRESULT setComImageFlags(DWORD mask); |
111 | HRESULT clearComImageFlags(DWORD mask); |
112 | DWORD getComImageFlags(); |
113 | |
114 | HRESULT setOutputFileName(__in LPWSTR outputFileName); |
115 | LPWSTR getOutputFileName(); |
116 | |
117 | HRESULT setResourceFileName(__in LPWSTR resourceFileName); |
118 | LPWSTR getResourceFileName(); |
119 | |
120 | HRESULT setLibraryName(__in LPWSTR libraryName); |
121 | LPWSTR getLibraryName(); |
122 | |
123 | HRESULT setDirectoryEntry(CeeSection §ion, ULONG entry, ULONG size, ULONG offset=0); |
124 | HRESULT computeSectionOffset(CeeSection §ion, __in char *ptr, |
125 | unsigned *offset); |
126 | HRESULT computeOffset(__in char *ptr, CeeSection **pSection, |
127 | unsigned *offset); |
128 | HRESULT (IMAGE_COR20_HEADER **); |
129 | |
130 | HRESULT getFileTimeStamp(DWORD *pTimeStamp); |
131 | |
132 | //<TODO>@FUTURE: this entry point is only here so that down level clients of this interface |
133 | // can import the method by name in the exports table using the original name. |
134 | // These things really ought to be exported through a v-table so there is no |
135 | // name mangling issues. It would make the export table much smaller as well.</TODO> |
136 | HRESULT emitLibraryName(IMetaDataEmit *emitter); |
137 | HRESULT setLibraryGuid(__in LPWSTR libraryGuid); |
138 | |
139 | HRESULT setDllSwitch(bool dllSwitch); |
140 | bool getDllSwitch(); |
141 | HRESULT setObjSwitch(bool objSwitch); |
142 | bool getObjSwitch(); |
143 | HRESULT EmitMacroDefinitions(void *pData, DWORD cData); |
144 | HRESULT setManifestEntry(ULONG size, ULONG offset); |
145 | HRESULT setStrongNameEntry(ULONG size, ULONG offset); |
146 | HRESULT setEnCRvaBase(ULONG dataBase, ULONG rdataBase); |
147 | HRESULT setVTableEntry(ULONG size, ULONG offset); |
148 | HRESULT setVTableEntry64(ULONG size, void* ptr); |
149 | |
150 | protected: |
151 | CeeFileGenWriter(); // ctor is protected |
152 | |
153 | HRESULT emitResourceSection(); |
154 | HRESULT emitExeMain(); |
155 | |
156 | HRESULT setAddrReloc(UCHAR *instrAddr, DWORD value); |
157 | HRESULT addAddrReloc(CeeSection &thisSection, UCHAR *instrAddr, DWORD offset, CeeSection *targetSection); |
158 | |
159 | HRESULT MapTokens(CeeGenTokenMapper *pMapper, IMetaDataImport *pImport); |
160 | HRESULT MapTokensForMethod(CeeGenTokenMapper *pMapper,BYTE *pCode, LPCWSTR szMethodName); |
161 | |
162 | #ifdef EMIT_FIXUPS |
163 | |
164 | HRESULT InitFixupSection(); |
165 | HRESULT UpdateFixups(); |
166 | HRESULT setEmitFixups(); |
167 | |
168 | #ifdef TEST_EMIT_FIXUPS |
169 | HRESULT TestEmitFixups(); |
170 | #endif |
171 | |
172 | public: |
173 | HRESULT addFixup(CeeSection& secFixups, unsigned offset, CeeSectionRelocType reloc, CeeSection * relativeTo = NULL, CeeSectionRelocExtra *extra = 0); |
174 | #endif |
175 | }; |
176 | |
177 | |
178 | inline PEWriter &CeeFileGenWriter::getPEWriter() |
179 | { |
180 | return (PEWriter &) *m_peSectionMan; |
181 | } |
182 | |
183 | inline LPWSTR CeeFileGenWriter::getOutputFileName() { |
184 | return m_outputFileName; |
185 | } |
186 | |
187 | inline LPWSTR CeeFileGenWriter::getResourceFileName() { |
188 | return m_resourceFileName; |
189 | } |
190 | |
191 | inline HRESULT CeeFileGenWriter::setDllSwitch(bool dllSwitch) { |
192 | if((m_dllSwitch = dllSwitch)) m_objSwitch = FALSE; return S_OK; |
193 | } |
194 | |
195 | inline bool CeeFileGenWriter::getDllSwitch() { |
196 | return m_dllSwitch; |
197 | } |
198 | |
199 | inline HRESULT CeeFileGenWriter::setObjSwitch(bool objSwitch) { |
200 | if((m_objSwitch = objSwitch)) m_dllSwitch = FALSE; return S_OK; |
201 | } |
202 | |
203 | inline bool CeeFileGenWriter::getObjSwitch() { |
204 | return m_objSwitch; |
205 | } |
206 | |
207 | inline LPWSTR CeeFileGenWriter::getLibraryName() { |
208 | return m_libraryName; |
209 | } |
210 | |
211 | inline mdMethodDef CeeFileGenWriter::getEntryPoint() { |
212 | return m_entryPoint; |
213 | } |
214 | |
215 | inline HRESULT CeeFileGenWriter::setEntryPoint(mdMethodDef method) { |
216 | m_entryPoint = method; |
217 | return S_OK; |
218 | } |
219 | |
220 | inline HRESULT CeeFileGenWriter::setComImageFlags(DWORD mask) { |
221 | m_comImageFlags |= mask; return S_OK; |
222 | } |
223 | |
224 | inline HRESULT CeeFileGenWriter::clearComImageFlags(DWORD mask) { |
225 | m_comImageFlags &= ~mask; return S_OK; |
226 | } |
227 | |
228 | inline DWORD CeeFileGenWriter::getComImageFlags() { |
229 | return m_comImageFlags; |
230 | } |
231 | |
232 | |
233 | // |
234 | #if defined(_IMAGE_FILE_4K_SECTION_ALIGNMENT_) |
235 | #define IMAGE_NT_OPTIONAL_HDR_SECTION_ALIGNMENT 0x1000 |
236 | #else |
237 | #define IMAGE_NT_OPTIONAL_HDR_SECTION_ALIGNMENT 0x2000 |
238 | #endif |
239 | |
240 | // The stub is always x86 so we always mark the image as x86 |
241 | #define IMAGE_FILE_MACHINE IMAGE_FILE_MACHINE_I386 |
242 | |
243 | |
244 | #endif // _CEEFILEGENWRITER_H_ |
245 | |
246 | |