summaryrefslogtreecommitdiff
path: root/src/inc/iceefilegen.h
blob: 7fa31d2930385cf6b7dee80df118c4c5bbafad0b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

/*****************************************************************************
 **                                                                         **
 ** ICeeFileGen.h - code generator interface.                               **
 **                                                                         **
 ** This interface provides functionality to create a CLR PE executable.    **
 ** This will typically be used by compilers to generate their compiled     **
 ** output executable.                                                      **
 **                                                                         **
 *****************************************************************************/

/*
  This is how this is typically used:
  
  // Step #1 ... Get CLR hosting API:
  #include <mscoree.h>
  #include <metahost.h>

  ICLRMetaHost * pMetaHost;
  CLRCreateInstance(CLSID_CLRMetaHost, IID_ICLRMetaHost, &pMetaHost); // defined in mscoree.h
  
  ICLRRuntimeInfo * pCLRRuntimeInfo;
  pMetaHost->GetRuntime(wszClrVersion, IID_ICLRRuntimeInfo, &pCLRRuntimeInfo);
  
  // Step #2 ... use mscorpe APIs to create a file generator
  CreateICeeFileGen(...);       // Get a ICeeFileGen
  
  CreateCeeFile(...);           // Get a HCEEFILE (called for every output file needed)
  SetOutputFileName(...);       // Set the name for the output file
  pEmit = IMetaDataEmit object; // Get a metadata emitter
  GetSectionBlock(...);, AddSectionReloc(...); ... // Get blocks, write non-metadata information, and add necessary relocation
  EmitMetaDataEx(pEmit);        // Write out the metadata
  GenerateCeeFile(...);         // Write out the file. Implicitly calls LinkCeeFile and FixupCeeFile
  
  DestroyICeeFileGen(...);      // Release the ICeeFileGen object
*/


#ifndef _ICEEFILEGEN_H_
#define _ICEEFILEGEN_H_

#include <ole2.h>
#include "cor.h"

class ICeeFileGen;

typedef void *HCEEFILE;

EXTERN_C HRESULT __stdcall CreateICeeFileGen(ICeeFileGen** pCeeFileGen);
EXTERN_C HRESULT __stdcall DestroyICeeFileGen(ICeeFileGen ** ppCeeFileGen);

typedef HRESULT (__stdcall * PFN_CreateICeeFileGen)(ICeeFileGen ** ceeFileGen);  // call this to instantiate an ICeeFileGen interface
typedef HRESULT (__stdcall * PFN_DestroyICeeFileGen)(ICeeFileGen ** ceeFileGen); // call this to delete an ICeeFileGen

#define ICEE_CREATE_FILE_PE32	       0x00000001  // Create a PE  (32-bit)
#define ICEE_CREATE_FILE_PE64	       0x00000002  // Create a PE+ (64-bit) 
#define ICEE_CREATE_FILE_CORMAIN_STUB  0x00000004  // add a mscoree!_Cor___Main call stub 
#define ICEE_CREATE_FILE_STRIP_RELOCS  0x00000008  // strip the .reloc section
#define ICEE_CREATE_FILE_EMIT_FIXUPS   0x00000010  // emit fixups for use by Vulcan

#define ICEE_CREATE_MACHINE_MASK       0x0000FF00  // space for up to 256 machine targets (note: most users just do a bit check, not an equality compare after applying the mask)
#define ICEE_CREATE_MACHINE_ILLEGAL    0x00000000  // An illegal machine name
#define ICEE_CREATE_MACHINE_I386       0x00000100  // Create a IMAGE_FILE_MACHINE_I386 
#define ICEE_CREATE_MACHINE_IA64       0x00000200  // Create a IMAGE_FILE_MACHINE_IA64
#define ICEE_CREATE_MACHINE_AMD64      0x00000400  // Create a IMAGE_FILE_MACHINE_AMD64
#define ICEE_CREATE_MACHINE_ARM        0x00000800  // Create a IMAGE_FILE_MACHINE_ARMNT
#define ICEE_CREATE_MACHINE_ARM64      0x00001000  // Create a IMAGE_FILE_MACHINE_ARM64

    // Pass this to CreateCeeFileEx to create a pure IL Exe or DLL
#define ICEE_CREATE_FILE_PURE_IL  ICEE_CREATE_FILE_PE32         | \
                                  ICEE_CREATE_FILE_CORMAIN_STUB | \
                                  ICEE_CREATE_MACHINE_I386

class ICeeFileGen {
  public:
    virtual HRESULT CreateCeeFile(HCEEFILE *ceeFile); // call this to instantiate a file handle

    // <TODO>@FUTURE: remove this function. We no longer support mdScope.</TODO>
    virtual HRESULT EmitMetaData (HCEEFILE ceeFile, IMetaDataEmit *emitter, mdScope scope);
    virtual HRESULT EmitLibraryName (HCEEFILE ceeFile, IMetaDataEmit *emitter, mdScope scope);
    virtual HRESULT EmitMethod (); // <TODO>@FUTURE: remove</TODO>
    virtual HRESULT GetMethodRVA (HCEEFILE ceeFile, ULONG codeOffset, ULONG *codeRVA); 
    virtual HRESULT EmitSignature (); // <TODO>@FUTURE: remove</TODO>

    virtual HRESULT EmitString (HCEEFILE ceeFile,_In_ LPWSTR strValue, ULONG *strRef);
    virtual HRESULT GenerateCeeFile (HCEEFILE ceeFile);

    virtual HRESULT SetOutputFileName (HCEEFILE ceeFile, _In_ LPWSTR outputFileName);
    _Return_type_success_(return == S_OK)
    virtual HRESULT GetOutputFileName (HCEEFILE ceeFile, _Out_ LPWSTR *outputFileName);

    virtual HRESULT SetResourceFileName (HCEEFILE ceeFile, _In_ LPWSTR resourceFileName);

    _Return_type_success_(return == S_OK)
    virtual HRESULT GetResourceFileName (HCEEFILE ceeFile, _Out_ LPWSTR *resourceFileName);

    virtual HRESULT SetImageBase(HCEEFILE ceeFile, size_t imageBase);

    virtual HRESULT SetSubsystem(HCEEFILE ceeFile, DWORD subsystem, DWORD major, DWORD minor);

    virtual HRESULT SetEntryClassToken (); //<TODO>@FUTURE: remove</TODO>
    virtual HRESULT GetEntryClassToken (); //<TODO>@FUTURE: remove</TODO>

    virtual HRESULT SetEntryPointDescr (); //<TODO>@FUTURE: remove</TODO>
    virtual HRESULT GetEntryPointDescr (); //<TODO>@FUTURE: remove</TODO>

    virtual HRESULT SetEntryPointFlags (); //<TODO>@FUTURE: remove</TODO>
    virtual HRESULT GetEntryPointFlags (); //<TODO>@FUTURE: remove</TODO>

    virtual HRESULT SetDllSwitch (HCEEFILE ceeFile, BOOL dllSwitch);
    virtual HRESULT GetDllSwitch (HCEEFILE ceeFile, BOOL *dllSwitch);

    virtual HRESULT SetLibraryName (HCEEFILE ceeFile, _In_ LPWSTR LibraryName);
    _Return_type_success_( return == S_OK )
    virtual HRESULT GetLibraryName (HCEEFILE ceeFile, _Out_ LPWSTR *LibraryName);

    virtual HRESULT SetLibraryGuid (HCEEFILE ceeFile, _In_ LPWSTR LibraryGuid);

    virtual HRESULT DestroyCeeFile(HCEEFILE *ceeFile); // call this to delete a file handle

    virtual HRESULT GetSectionCreate (HCEEFILE ceeFile, const char *name, DWORD flags, HCEESECTION *section);
    virtual HRESULT GetIlSection (HCEEFILE ceeFile, HCEESECTION *section);
    virtual HRESULT GetRdataSection (HCEEFILE ceeFile, HCEESECTION *section);

    virtual HRESULT GetSectionDataLen (HCEESECTION section, ULONG *dataLen);
    virtual HRESULT GetSectionBlock (HCEESECTION section, ULONG len, ULONG align=1, void **ppBytes=0);
    virtual HRESULT TruncateSection (HCEESECTION section, ULONG len);
    virtual HRESULT AddSectionReloc (HCEESECTION section, ULONG offset, HCEESECTION relativeTo, CeeSectionRelocType relocType);

    // deprecated: use SetDirectoryEntry instead
    virtual HRESULT SetSectionDirectoryEntry (HCEESECTION section, ULONG num);

    virtual HRESULT CreateSig (); //<TODO>@FUTURE: Remove</TODO>
    virtual HRESULT AddSigArg (); //<TODO>@FUTURE: Remove</TODO>
    virtual HRESULT SetSigReturnType (); //<TODO>@FUTURE: Remove</TODO>
    virtual HRESULT SetSigCallingConvention (); //<TODO>@FUTURE: Remove</TODO>
    virtual HRESULT DeleteSig (); //<TODO>@FUTURE: Remove</TODO>

    virtual HRESULT SetEntryPoint (HCEEFILE ceeFile, mdMethodDef method);
    virtual HRESULT GetEntryPoint (HCEEFILE ceeFile, mdMethodDef *method);

    virtual HRESULT SetComImageFlags (HCEEFILE ceeFile, DWORD mask);
    virtual HRESULT GetComImageFlags (HCEEFILE ceeFile, DWORD *mask);

    // get IMapToken interface for tracking mapped tokens
    virtual HRESULT GetIMapTokenIface(HCEEFILE ceeFile, IMetaDataEmit *emitter, IUnknown **pIMapToken);
    virtual HRESULT SetDirectoryEntry (HCEEFILE ceeFile, HCEESECTION section, ULONG num, ULONG size, ULONG offset = 0);

    // Write out the metadata in "emitter" to the metadata section in "ceeFile"
    // Use EmitMetaDataAt() for more control
    virtual HRESULT EmitMetaDataEx (HCEEFILE ceeFile, IMetaDataEmit *emitter); 

    virtual HRESULT EmitLibraryNameEx (HCEEFILE ceeFile, IMetaDataEmit *emitter);
    virtual HRESULT GetIMapTokenIfaceEx(HCEEFILE ceeFile, IMetaDataEmit *emitter, IUnknown **pIMapToken);

    virtual HRESULT EmitMacroDefinitions(HCEEFILE ceeFile, void *pData, DWORD cData);
    virtual HRESULT CreateCeeFileFromICeeGen(
        ICeeGen *pFromICeeGen, HCEEFILE *ceeFile, DWORD createFlags = ICEE_CREATE_FILE_PURE_IL); // call this to instantiate a file handle

    virtual HRESULT SetManifestEntry(HCEEFILE ceeFile, ULONG size, ULONG offset);

    virtual HRESULT SetEnCRVABase(HCEEFILE ceeFile, ULONG dataBase, ULONG rdataBase);
    virtual HRESULT GenerateCeeMemoryImage (HCEEFILE ceeFile, void **ppImage);

    virtual HRESULT ComputeSectionOffset(HCEESECTION section, _In_ char *ptr,
                                         unsigned *offset);
    
    virtual HRESULT ComputeOffset(HCEEFILE file, _In_ char *ptr,
                                  HCEESECTION *pSection, unsigned *offset);
    
    virtual HRESULT GetCorHeader(HCEEFILE ceeFile, 
                                 IMAGE_COR20_HEADER **header);
    
    // Layout the sections and assign their starting addresses
    virtual HRESULT LinkCeeFile (HCEEFILE ceeFile);     

    // Apply relocations to any pointer data. Also generate PE base relocs
    virtual HRESULT FixupCeeFile (HCEEFILE ceeFile);

    // Base RVA assinged to the section. To be called only after LinkCeeFile()
    virtual HRESULT GetSectionRVA (HCEESECTION section, ULONG *rva);
    
    _Return_type_success_(return == S_OK)
    virtual HRESULT ComputeSectionPointer(HCEESECTION section, ULONG offset,
                                          _Out_ char **ptr);

    virtual HRESULT SetObjSwitch (HCEEFILE ceeFile, BOOL objSwitch);
    virtual HRESULT GetObjSwitch (HCEEFILE ceeFile, BOOL *objSwitch);
    virtual HRESULT SetVTableEntry(HCEEFILE ceeFile, ULONG size, ULONG offset);
    // See the end of interface for another overload of AetVTableEntry

    virtual HRESULT SetStrongNameEntry(HCEEFILE ceeFile, ULONG size, ULONG offset);

    // Emit the metadata from "emitter".
    // If 'section != 0, it will put the data in 'buffer'.  This
    // buffer is assumed to be in 'section' at 'offset' and of size 'buffLen'
    // (should use GetSaveSize to insure that buffer is big enough
    virtual HRESULT EmitMetaDataAt (HCEEFILE ceeFile, IMetaDataEmit *emitter, 
                                    HCEESECTION section, DWORD offset, 
                                    BYTE* buffer, unsigned buffLen);

    virtual HRESULT GetFileTimeStamp (HCEEFILE ceeFile, DWORD *pTimeStamp);

    // Add a notification handler. If it implements an interface that
    // the ICeeFileGen understands, S_OK is returned. Otherwise,
    // E_NOINTERFACE.
    virtual HRESULT AddNotificationHandler(HCEEFILE ceeFile,
                                           IUnknown *pHandler);

    virtual HRESULT SetFileAlignment(HCEEFILE ceeFile, ULONG fileAlignment);

    virtual HRESULT ClearComImageFlags (HCEEFILE ceeFile, DWORD mask);

    // call this to instantiate a PE+ (64-bit PE file)
    virtual HRESULT CreateCeeFileEx(HCEEFILE *ceeFile, ULONG createFlags);
    virtual HRESULT SetImageBase64(HCEEFILE ceeFile, ULONGLONG imageBase);

    virtual HRESULT GetHeaderInfo (HCEEFILE ceeFile, PIMAGE_NT_HEADERS *ppNtHeaders,
                                                     PIMAGE_SECTION_HEADER *ppSections,
                                                     ULONG *pNumSections);

    // Seed file is a base file which is copied over into the output file
    // Note that there are restrictions on the seed file (the sections
    // cannot be relocated), and that the copy is not complete as the new
    // headers overwrite the seed file headers.
    virtual HRESULT CreateCeeFileEx2(HCEEFILE *ceeFile, ULONG createFlags,
                                     LPCWSTR seedFileName = NULL);

    virtual HRESULT SetVTableEntry64(HCEEFILE ceeFile, ULONG size, void* ptr);
};

#endif