Welcome to mirror list, hosted at ThFree Co, Russian Federation.

objwriter.h « ObjWriter « Native « src - github.com/mono/corert.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: bf9757b3703b0b4084df6fcd48dc60178aa24511 (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
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
//===---- objwriter.h --------------------------------*- C++ -*-===//
//
// object writer
//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license.
// See LICENSE file in the project root for full license information.
//
//===----------------------------------------------------------------------===//

#include "llvm/CodeGen/AsmPrinter.h"
#include "llvm/MC/MCCodeEmitter.h"
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCObjectFileInfo.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/DebugInfo/CodeView/TypeTableBuilder.h"

#include "cfi.h"
#include "jitDebugInfo.h"
#include <string>
#include <set>
#include "typeBuilder.h"

using namespace llvm;
using namespace llvm::codeview;

enum CustomSectionAttributes : int32_t {
  CustomSectionAttributes_ReadOnly = 0x0000,
  CustomSectionAttributes_Writeable = 0x0001,
  CustomSectionAttributes_Executable = 0x0002,
  CustomSectionAttributes_MachO_Init_Func_Pointers = 0x0100,
};

enum class RelocType {
  IMAGE_REL_BASED_ABSOLUTE = 0x00,
  IMAGE_REL_BASED_HIGHLOW = 0x03,
  IMAGE_REL_BASED_DIR64 = 0x0A,
  IMAGE_REL_BASED_REL32 = 0x10,
};

class ObjectWriter {
public:
  bool Init(StringRef FunctionName);
  void Finish();

  void SwitchSection(const char *SectionName,
                     CustomSectionAttributes attributes,
                     const char *ComdatName);
  void SetCodeSectionAttribute(const char *SectionName,
                               CustomSectionAttributes attributes,
                               const char *ComdatName);

  void EmitAlignment(int ByteAlignment);
  void EmitBlob(int BlobSize, const char *Blob);
  void EmitIntValue(uint64_t Value, unsigned Size);
  void EmitSymbolDef(const char *SymbolName);
  void EmitWinFrameInfo(const char *FunctionName, int StartOffset,
                        int EndOffset, const char *BlobSymbolName);
  int EmitSymbolRef(const char *SymbolName, RelocType RelocType, int Delta);

  void EmitDebugFileInfo(int FileId, const char *FileName);
  void EmitDebugFunctionInfo(const char *FunctionName, int FunctionSize);
  void EmitDebugVar(char *Name, int TypeIndex, bool IsParm, int RangeCount,
                    const ICorDebugInfo::NativeVarInfo *Ranges);
  void EmitDebugLoc(int NativeOffset, int FileId, int LineNumber,
                    int ColNumber);
  void EmitDebugModuleInfo();

  void EmitCFIStart(int Offset);
  void EmitCFIEnd(int Offset);
  void EmitCFILsda(const char *LsdaBlobSymbolName);
  void EmitCFICode(int Offset, const char *Blob);

  unsigned GetEnumTypeIndex(const EnumTypeDescriptor &TypeDescriptor,
                            const EnumRecordTypeDescriptor *TypeRecords);
  unsigned GetClassTypeIndex(const ClassTypeDescriptor &ClassDescriptor);
  unsigned GetCompleteClassTypeIndex(
      const ClassTypeDescriptor &ClassDescriptor,
      const ClassFieldsTypeDescriptior &ClassFieldsDescriptor,
      const DataFieldDescriptor *FieldsDescriptors);

  unsigned GetArrayTypeIndex(const ClassTypeDescriptor &ClassDescriptor,
                             const ArrayTypeDescriptor &ArrayDescriptor);

  unsigned GetPointerTypeIndex(const PointerTypeDescriptor& PointerDescriptor);

  unsigned GetMemberFunctionTypeIndex(const MemberFunctionTypeDescriptor& MemberDescriptor,
                                      uint32_t const *const ArgumentTypes);

  unsigned GetMemberFunctionId(const MemberFunctionIdTypeDescriptor& MemberIdDescriptor);

private:
  void EmitLabelDiff(const MCSymbol *From, const MCSymbol *To,
                     unsigned int Size = 4);
  void EmitSymRecord(int Size, SymbolRecordKind SymbolKind);
  void EmitCOFFSecRel32Value(MCExpr const *Value);

  void EmitVarDefRange(const MCSymbol *Fn, const LocalVariableAddrRange &Range);
  void EmitCVDebugVarInfo(const MCSymbol *Fn, const DebugVarInfo LocInfos[],
                          int NumVarInfos);
  void EmitCVDebugFunctionInfo(const char *FunctionName, int FunctionSize);

  const MCSymbolRefExpr *GetSymbolRefExpr(
      const char *SymbolName,
      MCSymbolRefExpr::VariantKind Kind = MCSymbolRefExpr::VK_None);

  MCSection *GetSection(const char *SectionName,
                        CustomSectionAttributes attributes,
                        const char *ComdatName);

  MCSection *GetSpecificSection(const char *SectionName,
                                CustomSectionAttributes attributes,
                                const char *ComdatName);

  void EmitCVUserDefinedTypesSymbols();

  void InitTripleName();
  Triple GetTriple();

private:
  std::unique_ptr<MCRegisterInfo> RegisterInfo;
  std::unique_ptr<MCAsmInfo> AsmInfo;
  std::unique_ptr<MCObjectFileInfo> ObjFileInfo;
  std::unique_ptr<MCContext> OutContext;
  MCAsmBackend *AsmBackend; // Owned by MCStreamer
  std::unique_ptr<MCInstrInfo> InstrInfo;
  std::unique_ptr<MCSubtargetInfo> SubtargetInfo;
  MCCodeEmitter *CodeEmitter; // Owned by MCStreamer
  std::unique_ptr<TargetMachine> TMachine;
  std::unique_ptr<AsmPrinter> AssemblerPrinter;
  MCAssembler *Assembler; // Owned by MCStreamer

  std::unique_ptr<raw_fd_ostream> OS;
  MCTargetOptions TargetMOptions;
  bool FrameOpened;
  std::vector<DebugVarInfo> DebugVarInfos;

  std::set<MCSection *> Sections;
  int FuncId;

  UserDefinedTypesBuilder TypeBuilder;

  std::string TripleName;

  MCObjectStreamer *Streamer; // Owned by AsmPrinter
};

// When object writer is created/initialized successfully, it is returned.
// Or null object is returned. Client should check this.
extern "C" ObjectWriter *InitObjWriter(const char *ObjectFilePath) {
  ObjectWriter *OW = new ObjectWriter();
  if (OW->Init(ObjectFilePath)) {
    return OW;
  }
  delete OW;
  return nullptr;
}

extern "C" void FinishObjWriter(ObjectWriter *OW) {
  assert(OW && "ObjWriter is null");
  OW->Finish();
  delete OW;
}

extern "C" void SwitchSection(ObjectWriter *OW, const char *SectionName,
                              CustomSectionAttributes attributes,
                              const char *ComdatName) {
  assert(OW && "ObjWriter is null");
  OW->SwitchSection(SectionName, attributes, ComdatName);
}

extern "C" void SetCodeSectionAttribute(ObjectWriter *OW,
                                        const char *SectionName,
                                        CustomSectionAttributes attributes,
                                        const char *ComdatName) {
  assert(OW && "ObjWriter is null");
  OW->SetCodeSectionAttribute(SectionName, attributes, ComdatName);
}

extern "C" void EmitAlignment(ObjectWriter *OW, int ByteAlignment) {
  assert(OW && "ObjWriter is null");
  OW->EmitAlignment(ByteAlignment);
}

extern "C" void EmitBlob(ObjectWriter *OW, int BlobSize, const char *Blob) {
  assert(OW && "ObjWriter null");
  OW->EmitBlob(BlobSize, Blob);
}

extern "C" void EmitIntValue(ObjectWriter *OW, uint64_t Value, unsigned Size) {
  assert(OW && "ObjWriter is null");
  OW->EmitIntValue(Value, Size);
}

extern "C" void EmitSymbolDef(ObjectWriter *OW, const char *SymbolName) {
  assert(OW && "ObjWriter is null");
  OW->EmitSymbolDef(SymbolName);
}

extern "C" int EmitSymbolRef(ObjectWriter *OW, const char *SymbolName,
                             RelocType RelocType, int Delta) {
  assert(OW && "ObjWriter is null");
  return OW->EmitSymbolRef(SymbolName, RelocType, Delta);
}

extern "C" void EmitWinFrameInfo(ObjectWriter *OW, const char *FunctionName,
                                 int StartOffset, int EndOffset,
                                 const char *BlobSymbolName) {
  assert(OW && "ObjWriter is null");
  OW->EmitWinFrameInfo(FunctionName, StartOffset, EndOffset, BlobSymbolName);
}

extern "C" void EmitCFIStart(ObjectWriter *OW, int Offset) {
  assert(OW && "ObjWriter is null");
  OW->EmitCFIStart(Offset);
}

extern "C" void EmitCFIEnd(ObjectWriter *OW, int Offset) {
  assert(OW && "ObjWriter is null");
  OW->EmitCFIEnd(Offset);
}

extern "C" void EmitCFILsda(ObjectWriter *OW, const char *LsdaBlobSymbolName) {
  assert(OW && "ObjWriter is null");
  OW->EmitCFILsda(LsdaBlobSymbolName);
}

extern "C" void EmitCFICode(ObjectWriter *OW, int Offset, const char *Blob) {
  assert(OW && "ObjWriter is null");
  OW->EmitCFICode(Offset, Blob);
}

extern "C" void EmitDebugFileInfo(ObjectWriter *OW, int FileId,
                                  const char *FileName) {
  assert(OW && "ObjWriter is null");
  OW->EmitDebugFileInfo(FileId, FileName);
}

extern "C" void EmitDebugFunctionInfo(ObjectWriter *OW,
                                      const char *FunctionName,
                                      int FunctionSize) {
  assert(OW && "ObjWriter is null");
  OW->EmitDebugFunctionInfo(FunctionName, FunctionSize);
}

extern "C" void EmitDebugVar(ObjectWriter *OW, char *Name, int TypeIndex,
                             bool IsParam, int RangeCount,
                             ICorDebugInfo::NativeVarInfo *Ranges) {
  assert(OW && "ObjWriter is null");
  OW->EmitDebugVar(Name, TypeIndex, IsParam, RangeCount, Ranges);
}

extern "C" void EmitDebugLoc(ObjectWriter *OW, int NativeOffset, int FileId,
                             int LineNumber, int ColNumber) {
  assert(OW && "ObjWriter is null");
  OW->EmitDebugLoc(NativeOffset, FileId, LineNumber, ColNumber);
}

// This should be invoked at the end of module emission to finalize
// debug module info.
extern "C" void EmitDebugModuleInfo(ObjectWriter *OW) {
  assert(OW && "ObjWriter is null");
  OW->EmitDebugModuleInfo();
}

extern "C" unsigned GetEnumTypeIndex(ObjectWriter *OW,
                                     EnumTypeDescriptor TypeDescriptor,
                                     EnumRecordTypeDescriptor *TypeRecords) {
  assert(OW && "ObjWriter is null");
  return OW->GetEnumTypeIndex(TypeDescriptor, TypeRecords);
}

extern "C" unsigned GetClassTypeIndex(ObjectWriter *OW,
                                      ClassTypeDescriptor ClassDescriptor) {
  assert(OW && "ObjWriter is null");
  return OW->GetClassTypeIndex(ClassDescriptor);
}

extern "C" unsigned
GetCompleteClassTypeIndex(ObjectWriter *OW, ClassTypeDescriptor ClassDescriptor,
                          ClassFieldsTypeDescriptior ClassFieldsDescriptor,
                          DataFieldDescriptor *FieldsDescriptors) {
  assert(OW && "ObjWriter is null");
  return OW->GetCompleteClassTypeIndex(ClassDescriptor, ClassFieldsDescriptor,
                                       FieldsDescriptors);
}

extern "C" unsigned GetArrayTypeIndex(ObjectWriter *OW,
                                      ClassTypeDescriptor ClassDescriptor,
                                      ArrayTypeDescriptor ArrayDescriptor) {
  assert(OW && "ObjWriter is null");
  return OW->GetArrayTypeIndex(ClassDescriptor, ArrayDescriptor);
}

extern "C" unsigned GetPointerTypeIndex(ObjectWriter *OW,
    PointerTypeDescriptor PointerDescriptor) {
    assert(OW && "ObjWriter is null");
    return OW->GetPointerTypeIndex(PointerDescriptor);
}

extern "C" unsigned GetMemberFunctionTypeIndex(ObjectWriter *OW,
    MemberFunctionTypeDescriptor MemberDescriptor,
    uint32_t *ArgumentTypes) {
    assert(OW && "ObjWriter is null");
    return OW->GetMemberFunctionTypeIndex(MemberDescriptor, ArgumentTypes);
}

extern "C" unsigned GetMemberFunctionIdTypeIndex(ObjectWriter *OW,
    MemberFunctionIdTypeDescriptor MemberIdDescriptor) {
    assert(OW && "ObjWriter is null");
    return OW->GetMemberFunctionId(MemberIdDescriptor);
}