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
21class PEWriter;
22class CeeFileGenWriter;
23
24// default setting for PE file
25const UINT32 CEE_IMAGE_BASE_32 = 0x00400000;
26const UINT64 CEE_IMAGE_BASE_64 = UI64(0x0000000140000000);
27const int CEE_IMAGE_SUBSYSTEM_MAJOR_VERSION = 4;
28const int CEE_IMAGE_SUBSYSTEM_MINOR_VERSION = 0;
29
30class 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();
84public:
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 &section, ULONG entry, ULONG size, ULONG offset=0);
124 HRESULT computeSectionOffset(CeeSection &section, __in char *ptr,
125 unsigned *offset);
126 HRESULT computeOffset(__in char *ptr, CeeSection **pSection,
127 unsigned *offset);
128 HRESULT getCorHeader(IMAGE_COR20_HEADER **ppHeader);
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
150protected:
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
172public:
173 HRESULT addFixup(CeeSection& secFixups, unsigned offset, CeeSectionRelocType reloc, CeeSection * relativeTo = NULL, CeeSectionRelocExtra *extra = 0);
174#endif
175};
176
177
178inline PEWriter &CeeFileGenWriter::getPEWriter()
179{
180 return (PEWriter &) *m_peSectionMan;
181}
182
183inline LPWSTR CeeFileGenWriter::getOutputFileName() {
184 return m_outputFileName;
185}
186
187inline LPWSTR CeeFileGenWriter::getResourceFileName() {
188 return m_resourceFileName;
189}
190
191inline HRESULT CeeFileGenWriter::setDllSwitch(bool dllSwitch) {
192 if((m_dllSwitch = dllSwitch)) m_objSwitch = FALSE; return S_OK;
193}
194
195inline bool CeeFileGenWriter::getDllSwitch() {
196 return m_dllSwitch;
197}
198
199inline HRESULT CeeFileGenWriter::setObjSwitch(bool objSwitch) {
200 if((m_objSwitch = objSwitch)) m_dllSwitch = FALSE; return S_OK;
201}
202
203inline bool CeeFileGenWriter::getObjSwitch() {
204 return m_objSwitch;
205}
206
207inline LPWSTR CeeFileGenWriter::getLibraryName() {
208 return m_libraryName;
209}
210
211inline mdMethodDef CeeFileGenWriter::getEntryPoint() {
212 return m_entryPoint;
213}
214
215inline HRESULT CeeFileGenWriter::setEntryPoint(mdMethodDef method) {
216 m_entryPoint = method;
217 return S_OK;
218}
219
220inline HRESULT CeeFileGenWriter::setComImageFlags(DWORD mask) {
221 m_comImageFlags |= mask; return S_OK;
222}
223
224inline HRESULT CeeFileGenWriter::clearComImageFlags(DWORD mask) {
225 m_comImageFlags &= ~mask; return S_OK;
226}
227
228inline 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