/src/keystone/llvm/lib/MC/MCStreamer.cpp
Line | Count | Source |
1 | | //===- lib/MC/MCStreamer.cpp - Streaming Machine Code Output --------------===// |
2 | | // |
3 | | // The LLVM Compiler Infrastructure |
4 | | // |
5 | | // This file is distributed under the University of Illinois Open Source |
6 | | // License. See LICENSE.TXT for details. |
7 | | // |
8 | | //===----------------------------------------------------------------------===// |
9 | | |
10 | | #include "llvm/MC/MCStreamer.h" |
11 | | #include "llvm/ADT/SmallString.h" |
12 | | #include "llvm/ADT/Twine.h" |
13 | | #include "llvm/MC/MCAsmBackend.h" |
14 | | #include "llvm/MC/MCAsmInfo.h" |
15 | | #include "llvm/MC/MCContext.h" |
16 | | #include "llvm/MC/MCExpr.h" |
17 | | #include "llvm/MC/MCInst.h" |
18 | | #include "llvm/MC/MCObjectFileInfo.h" |
19 | | #include "llvm/MC/MCObjectWriter.h" |
20 | | #include "llvm/MC/MCSection.h" |
21 | | #include "llvm/MC/MCSymbol.h" |
22 | | #include "llvm/MC/MCWin64EH.h" |
23 | | #include "llvm/Support/ErrorHandling.h" |
24 | | #include "llvm/Support/LEB128.h" |
25 | | #include "llvm/Support/raw_ostream.h" |
26 | | #include <cstdlib> |
27 | | |
28 | | //#include <iostream> |
29 | | |
30 | | using namespace llvm_ks; |
31 | | |
32 | | // Pin the vtables to this file. |
33 | 117k | MCTargetStreamer::~MCTargetStreamer() {} |
34 | | |
35 | 117k | MCTargetStreamer::MCTargetStreamer(MCStreamer &S) : Streamer(S) { |
36 | 117k | S.setTargetStreamer(this); |
37 | 117k | } |
38 | | |
39 | 824k | void MCTargetStreamer::emitLabel(MCSymbol *Symbol) {} |
40 | | |
41 | 12.5k | void MCTargetStreamer::finish() {} |
42 | | |
43 | 565k | void MCTargetStreamer::emitAssignment(MCSymbol *Symbol, const MCExpr *Value) {} |
44 | | |
45 | | MCStreamer::MCStreamer(MCContext &Ctx) |
46 | 173k | : Context(Ctx), CurrentWinFrameInfo(nullptr) { |
47 | 173k | SectionStack.push_back(std::pair<MCSectionSubPair, MCSectionSubPair>()); |
48 | 173k | } |
49 | | |
50 | 173k | MCStreamer::~MCStreamer() { |
51 | 173k | for (unsigned i = 0; i < getNumWinFrameInfos(); ++i) |
52 | 0 | delete WinFrameInfos[i]; |
53 | 173k | } |
54 | | |
55 | 0 | void MCStreamer::reset() { |
56 | 0 | DwarfFrameInfos.clear(); |
57 | 0 | for (unsigned i = 0; i < getNumWinFrameInfos(); ++i) |
58 | 0 | delete WinFrameInfos[i]; |
59 | 0 | WinFrameInfos.clear(); |
60 | 0 | CurrentWinFrameInfo = nullptr; |
61 | 0 | SymbolOrdering.clear(); |
62 | 0 | SectionStack.clear(); |
63 | 0 | SectionStack.push_back(std::pair<MCSectionSubPair, MCSectionSubPair>()); |
64 | 0 | } |
65 | | |
66 | 0 | raw_ostream &MCStreamer::GetCommentOS() { |
67 | | // By default, discard comments. |
68 | 0 | return nulls(); |
69 | 0 | } |
70 | | |
71 | 0 | void MCStreamer::emitRawComment(const Twine &T, bool TabPrefix) {} |
72 | | |
73 | 0 | void MCStreamer::generateCompactUnwindEncodings(MCAsmBackend *MAB) { |
74 | 0 | for (auto &FI : DwarfFrameInfos) |
75 | 0 | FI.CompactUnwindEncoding = |
76 | 0 | (MAB ? MAB->generateCompactUnwindEncoding(FI.Instructions) : 0); |
77 | 0 | } |
78 | | |
79 | | /// EmitIntValue - Special case of EmitValue that avoids the client having to |
80 | | /// pass in a MCExpr for constant integers. |
81 | | void MCStreamer::EmitIntValue(uint64_t Value, unsigned Size, bool &Error) |
82 | 624M | { |
83 | 624M | Error = false; |
84 | | //assert(1 <= Size && Size <= 8 && "Invalid size"); |
85 | 624M | if (1 > Size || Size > 8) { |
86 | 1.81k | Error = true; |
87 | 1.81k | return; |
88 | 1.81k | } |
89 | | //assert((isUIntN(8 * Size, Value) || isIntN(8 * Size, Value)) && |
90 | | // "Invalid size"); |
91 | 624M | if (!isUIntN(8 * Size, Value) && !isIntN(8 * Size, Value)) { |
92 | 78.1k | Error = true; |
93 | 78.1k | return; |
94 | 78.1k | } |
95 | 624M | char buf[8]; |
96 | 624M | const bool isLittleEndian = Context.getAsmInfo()->isLittleEndian(); |
97 | 1.78G | for (unsigned i = 0; i != Size; ++i) { |
98 | 1.16G | unsigned index = isLittleEndian ? i : (Size - i - 1); |
99 | 1.16G | buf[i] = uint8_t(Value >> (index * 8)); |
100 | 1.16G | } |
101 | 624M | EmitBytes(StringRef(buf, Size)); |
102 | 624M | } |
103 | | |
104 | | /// EmitULEB128Value - Special case of EmitULEB128Value that avoids the |
105 | | /// client having to pass in a MCExpr for constant integers. |
106 | 34 | void MCStreamer::EmitULEB128IntValue(uint64_t Value, unsigned Padding) { |
107 | 34 | SmallString<128> Tmp; |
108 | 34 | raw_svector_ostream OSE(Tmp); |
109 | 34 | encodeULEB128(Value, OSE, Padding); |
110 | 34 | EmitBytes(OSE.str()); |
111 | 34 | } |
112 | | |
113 | | /// EmitSLEB128Value - Special case of EmitSLEB128Value that avoids the |
114 | | /// client having to pass in a MCExpr for constant integers. |
115 | 77 | void MCStreamer::EmitSLEB128IntValue(int64_t Value) { |
116 | 77 | SmallString<128> Tmp; |
117 | 77 | raw_svector_ostream OSE(Tmp); |
118 | 77 | encodeSLEB128(Value, OSE); |
119 | 77 | EmitBytes(OSE.str()); |
120 | 77 | } |
121 | | |
122 | 1.13M | void MCStreamer::EmitValue(const MCExpr *Value, unsigned Size, SMLoc Loc) { |
123 | 1.13M | EmitValueImpl(Value, Size, Loc); |
124 | 1.13M | } |
125 | | |
126 | | void MCStreamer::EmitSymbolValue(const MCSymbol *Sym, unsigned Size, |
127 | 0 | bool IsSectionRelative) { |
128 | 0 | assert((!IsSectionRelative || Size == 4) && |
129 | 0 | "SectionRelative value requires 4-bytes"); |
130 | | |
131 | 0 | if (!IsSectionRelative) |
132 | 0 | EmitValueImpl(MCSymbolRefExpr::create(Sym, getContext()), Size); |
133 | 0 | else |
134 | 0 | EmitCOFFSecRel32(Sym); |
135 | 0 | } |
136 | | |
137 | 0 | void MCStreamer::EmitGPRel64Value(const MCExpr *Value) { |
138 | 0 | report_fatal_error("unsupported directive in streamer"); |
139 | 0 | } |
140 | | |
141 | 0 | void MCStreamer::EmitGPRel32Value(const MCExpr *Value) { |
142 | 0 | report_fatal_error("unsupported directive in streamer"); |
143 | 0 | } |
144 | | |
145 | | /// EmitFill - Emit NumBytes bytes worth of the value specified by |
146 | | /// FillValue. This implements directives such as '.space'. |
147 | 0 | void MCStreamer::EmitFill(uint64_t NumBytes, uint8_t FillValue) { |
148 | 0 | const MCExpr *E = MCConstantExpr::create(FillValue, getContext()); |
149 | 0 | for (uint64_t i = 0, e = NumBytes; i != e; ++i) |
150 | 0 | EmitValue(E, 1); |
151 | 0 | } |
152 | | |
153 | | /// The implementation in this class just redirects to EmitFill. |
154 | 541 | void MCStreamer::EmitZeros(uint64_t NumBytes) { |
155 | 541 | EmitFill(NumBytes, 0); |
156 | 541 | } |
157 | | |
158 | | unsigned MCStreamer::EmitDwarfFileDirective(unsigned FileNo, |
159 | | StringRef Directory, |
160 | 359 | StringRef Filename, unsigned CUID) { |
161 | 359 | return getContext().getDwarfFile(Directory, Filename, FileNo, CUID); |
162 | 359 | } |
163 | | |
164 | | void MCStreamer::EmitDwarfLocDirective(unsigned FileNo, unsigned Line, |
165 | | unsigned Column, unsigned Flags, |
166 | | unsigned Isa, |
167 | | unsigned Discriminator, |
168 | 0 | StringRef FileName) { |
169 | 0 | getContext().setCurrentDwarfLoc(FileNo, Line, Column, Flags, Isa, |
170 | 0 | Discriminator); |
171 | 0 | } |
172 | | |
173 | 0 | MCSymbol *MCStreamer::getDwarfLineTableSymbol(unsigned CUID) { |
174 | 0 | MCDwarfLineTable &Table = getContext().getMCDwarfLineTable(CUID); |
175 | 0 | if (!Table.getLabel()) { |
176 | 0 | StringRef Prefix = Context.getAsmInfo()->getPrivateGlobalPrefix(); |
177 | 0 | Table.setLabel( |
178 | 0 | Context.getOrCreateSymbol(Prefix + "line_table_start" + Twine(CUID))); |
179 | 0 | } |
180 | 0 | return Table.getLabel(); |
181 | 0 | } |
182 | | |
183 | 0 | MCDwarfFrameInfo *MCStreamer::getCurrentDwarfFrameInfo() { |
184 | 0 | if (DwarfFrameInfos.empty()) |
185 | 0 | return nullptr; |
186 | 0 | return &DwarfFrameInfos.back(); |
187 | 0 | } |
188 | | |
189 | 0 | void MCStreamer::EnsureValidDwarfFrame() { |
190 | 0 | MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo(); |
191 | 0 | if (!CurFrame || CurFrame->End) |
192 | 0 | report_fatal_error("No open frame"); |
193 | 0 | } |
194 | | |
195 | 0 | unsigned MCStreamer::EmitCVFileDirective(unsigned FileNo, StringRef Filename) { |
196 | 0 | return getContext().getCVFile(Filename, FileNo); |
197 | 0 | } |
198 | | |
199 | | void MCStreamer::EmitCVLocDirective(unsigned FunctionId, unsigned FileNo, |
200 | | unsigned Line, unsigned Column, |
201 | | bool PrologueEnd, bool IsStmt, |
202 | 0 | StringRef FileName) { |
203 | 0 | getContext().setCurrentCVLoc(FunctionId, FileNo, Line, Column, PrologueEnd, |
204 | 0 | IsStmt); |
205 | 0 | } |
206 | | |
207 | | void MCStreamer::EmitCVLinetableDirective(unsigned FunctionId, |
208 | | const MCSymbol *Begin, |
209 | 0 | const MCSymbol *End) {} |
210 | | |
211 | | void MCStreamer::EmitCVInlineLinetableDirective( |
212 | | unsigned PrimaryFunctionId, unsigned SourceFileId, unsigned SourceLineNum, |
213 | 0 | ArrayRef<unsigned> SecondaryFunctionIds) {} |
214 | | |
215 | | void MCStreamer::EmitEHSymAttributes(const MCSymbol *Symbol, |
216 | 0 | MCSymbol *EHSymbol) { |
217 | 0 | } |
218 | | |
219 | 0 | void MCStreamer::InitSections(bool NoExecStack) { |
220 | 0 | SwitchSection(getContext().getObjectFileInfo()->getTextSection()); |
221 | 0 | } |
222 | | |
223 | 0 | void MCStreamer::AssignFragment(MCSymbol *Symbol, MCFragment *Fragment) { |
224 | 0 | assert(Fragment); |
225 | 0 | Symbol->setFragment(Fragment); |
226 | | |
227 | | // As we emit symbols into a section, track the order so that they can |
228 | | // be sorted upon later. Zero is reserved to mean 'unemitted'. |
229 | 0 | SymbolOrdering[Symbol] = 1 + SymbolOrdering.size(); |
230 | 0 | } |
231 | | |
232 | 1.45M | void MCStreamer::EmitLabel(MCSymbol *Symbol) { |
233 | 1.45M | assert(!Symbol->isVariable() && "Cannot emit a variable symbol!"); |
234 | 1.45M | assert(getCurrentSection().first && "Cannot emit before setting section!"); |
235 | 1.45M | assert(!Symbol->getFragment() && "Unexpected fragment on symbol data!"); |
236 | 1.45M | Symbol->setFragment(&getCurrentSectionOnly()->getDummyFragment()); |
237 | | |
238 | 1.45M | MCTargetStreamer *TS = getTargetStreamer(); |
239 | 1.45M | if (TS) |
240 | 824k | TS->emitLabel(Symbol); |
241 | 1.45M | } |
242 | | |
243 | 0 | void MCStreamer::EmitCFISections(bool EH, bool Debug) { |
244 | 0 | assert(EH || Debug); |
245 | 0 | } |
246 | | |
247 | 0 | void MCStreamer::EmitCFIStartProc(bool IsSimple) { |
248 | 0 | MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo(); |
249 | 0 | if (CurFrame && !CurFrame->End) |
250 | 0 | report_fatal_error("Starting a frame before finishing the previous one!"); |
251 | | |
252 | 0 | MCDwarfFrameInfo Frame; |
253 | 0 | Frame.IsSimple = IsSimple; |
254 | 0 | EmitCFIStartProcImpl(Frame); |
255 | |
|
256 | 0 | const MCAsmInfo* MAI = Context.getAsmInfo(); |
257 | 0 | if (MAI) { |
258 | 0 | for (const MCCFIInstruction& Inst : MAI->getInitialFrameState()) { |
259 | 0 | if (Inst.getOperation() == MCCFIInstruction::OpDefCfa || |
260 | 0 | Inst.getOperation() == MCCFIInstruction::OpDefCfaRegister) { |
261 | 0 | Frame.CurrentCfaRegister = Inst.getRegister(); |
262 | 0 | } |
263 | 0 | } |
264 | 0 | } |
265 | |
|
266 | 0 | DwarfFrameInfos.push_back(Frame); |
267 | 0 | } |
268 | | |
269 | 0 | void MCStreamer::EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) { |
270 | 0 | } |
271 | | |
272 | 0 | void MCStreamer::EmitCFIEndProc() { |
273 | 0 | EnsureValidDwarfFrame(); |
274 | 0 | MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo(); |
275 | 0 | EmitCFIEndProcImpl(*CurFrame); |
276 | 0 | } |
277 | | |
278 | 0 | void MCStreamer::EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) { |
279 | | // Put a dummy non-null value in Frame.End to mark that this frame has been |
280 | | // closed. |
281 | 0 | Frame.End = (MCSymbol *) 1; |
282 | 0 | } |
283 | | |
284 | 0 | MCSymbol *MCStreamer::EmitCFICommon() { |
285 | 0 | EnsureValidDwarfFrame(); |
286 | 0 | MCSymbol *Label = getContext().createTempSymbol(); |
287 | 0 | EmitLabel(Label); |
288 | 0 | return Label; |
289 | 0 | } |
290 | | |
291 | 0 | void MCStreamer::EmitCFIDefCfa(int64_t Register, int64_t Offset) { |
292 | 0 | MCSymbol *Label = EmitCFICommon(); |
293 | 0 | MCCFIInstruction Instruction = |
294 | 0 | MCCFIInstruction::createDefCfa(Label, Register, Offset); |
295 | 0 | MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo(); |
296 | 0 | CurFrame->Instructions.push_back(Instruction); |
297 | 0 | CurFrame->CurrentCfaRegister = static_cast<unsigned>(Register); |
298 | 0 | } |
299 | | |
300 | 0 | void MCStreamer::EmitCFIDefCfaOffset(int64_t Offset) { |
301 | 0 | MCSymbol *Label = EmitCFICommon(); |
302 | 0 | MCCFIInstruction Instruction = |
303 | 0 | MCCFIInstruction::createDefCfaOffset(Label, Offset); |
304 | 0 | MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo(); |
305 | 0 | CurFrame->Instructions.push_back(Instruction); |
306 | 0 | } |
307 | | |
308 | 0 | void MCStreamer::EmitCFIAdjustCfaOffset(int64_t Adjustment) { |
309 | 0 | MCSymbol *Label = EmitCFICommon(); |
310 | 0 | MCCFIInstruction Instruction = |
311 | 0 | MCCFIInstruction::createAdjustCfaOffset(Label, Adjustment); |
312 | 0 | MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo(); |
313 | 0 | CurFrame->Instructions.push_back(Instruction); |
314 | 0 | } |
315 | | |
316 | 0 | void MCStreamer::EmitCFIDefCfaRegister(int64_t Register) { |
317 | 0 | MCSymbol *Label = EmitCFICommon(); |
318 | 0 | MCCFIInstruction Instruction = |
319 | 0 | MCCFIInstruction::createDefCfaRegister(Label, Register); |
320 | 0 | MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo(); |
321 | 0 | CurFrame->Instructions.push_back(Instruction); |
322 | 0 | CurFrame->CurrentCfaRegister = static_cast<unsigned>(Register); |
323 | 0 | } |
324 | | |
325 | 0 | void MCStreamer::EmitCFIOffset(int64_t Register, int64_t Offset) { |
326 | 0 | MCSymbol *Label = EmitCFICommon(); |
327 | 0 | MCCFIInstruction Instruction = |
328 | 0 | MCCFIInstruction::createOffset(Label, Register, Offset); |
329 | 0 | MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo(); |
330 | 0 | CurFrame->Instructions.push_back(Instruction); |
331 | 0 | } |
332 | | |
333 | 0 | void MCStreamer::EmitCFIRelOffset(int64_t Register, int64_t Offset) { |
334 | 0 | MCSymbol *Label = EmitCFICommon(); |
335 | 0 | MCCFIInstruction Instruction = |
336 | 0 | MCCFIInstruction::createRelOffset(Label, Register, Offset); |
337 | 0 | MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo(); |
338 | 0 | CurFrame->Instructions.push_back(Instruction); |
339 | 0 | } |
340 | | |
341 | | void MCStreamer::EmitCFIPersonality(const MCSymbol *Sym, |
342 | 0 | unsigned Encoding) { |
343 | 0 | EnsureValidDwarfFrame(); |
344 | 0 | MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo(); |
345 | 0 | CurFrame->Personality = Sym; |
346 | 0 | CurFrame->PersonalityEncoding = Encoding; |
347 | 0 | } |
348 | | |
349 | 0 | void MCStreamer::EmitCFILsda(const MCSymbol *Sym, unsigned Encoding) { |
350 | 0 | EnsureValidDwarfFrame(); |
351 | 0 | MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo(); |
352 | 0 | CurFrame->Lsda = Sym; |
353 | 0 | CurFrame->LsdaEncoding = Encoding; |
354 | 0 | } |
355 | | |
356 | 0 | void MCStreamer::EmitCFIRememberState() { |
357 | 0 | MCSymbol *Label = EmitCFICommon(); |
358 | 0 | MCCFIInstruction Instruction = MCCFIInstruction::createRememberState(Label); |
359 | 0 | MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo(); |
360 | 0 | CurFrame->Instructions.push_back(Instruction); |
361 | 0 | } |
362 | | |
363 | 0 | void MCStreamer::EmitCFIRestoreState() { |
364 | | // FIXME: Error if there is no matching cfi_remember_state. |
365 | 0 | MCSymbol *Label = EmitCFICommon(); |
366 | 0 | MCCFIInstruction Instruction = MCCFIInstruction::createRestoreState(Label); |
367 | 0 | MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo(); |
368 | 0 | CurFrame->Instructions.push_back(Instruction); |
369 | 0 | } |
370 | | |
371 | 0 | void MCStreamer::EmitCFISameValue(int64_t Register) { |
372 | 0 | MCSymbol *Label = EmitCFICommon(); |
373 | 0 | MCCFIInstruction Instruction = |
374 | 0 | MCCFIInstruction::createSameValue(Label, Register); |
375 | 0 | MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo(); |
376 | 0 | CurFrame->Instructions.push_back(Instruction); |
377 | 0 | } |
378 | | |
379 | 0 | void MCStreamer::EmitCFIRestore(int64_t Register) { |
380 | 0 | MCSymbol *Label = EmitCFICommon(); |
381 | 0 | MCCFIInstruction Instruction = |
382 | 0 | MCCFIInstruction::createRestore(Label, Register); |
383 | 0 | MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo(); |
384 | 0 | CurFrame->Instructions.push_back(Instruction); |
385 | 0 | } |
386 | | |
387 | 0 | void MCStreamer::EmitCFIEscape(StringRef Values) { |
388 | 0 | MCSymbol *Label = EmitCFICommon(); |
389 | 0 | MCCFIInstruction Instruction = MCCFIInstruction::createEscape(Label, Values); |
390 | 0 | MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo(); |
391 | 0 | CurFrame->Instructions.push_back(Instruction); |
392 | 0 | } |
393 | | |
394 | 0 | void MCStreamer::EmitCFIGnuArgsSize(int64_t Size) { |
395 | 0 | MCSymbol *Label = EmitCFICommon(); |
396 | 0 | MCCFIInstruction Instruction = |
397 | 0 | MCCFIInstruction::createGnuArgsSize(Label, Size); |
398 | 0 | MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo(); |
399 | 0 | CurFrame->Instructions.push_back(Instruction); |
400 | 0 | } |
401 | | |
402 | 0 | void MCStreamer::EmitCFISignalFrame() { |
403 | 0 | EnsureValidDwarfFrame(); |
404 | 0 | MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo(); |
405 | 0 | CurFrame->IsSignalFrame = true; |
406 | 0 | } |
407 | | |
408 | 0 | void MCStreamer::EmitCFIUndefined(int64_t Register) { |
409 | 0 | MCSymbol *Label = EmitCFICommon(); |
410 | 0 | MCCFIInstruction Instruction = |
411 | 0 | MCCFIInstruction::createUndefined(Label, Register); |
412 | 0 | MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo(); |
413 | 0 | CurFrame->Instructions.push_back(Instruction); |
414 | 0 | } |
415 | | |
416 | 0 | void MCStreamer::EmitCFIRegister(int64_t Register1, int64_t Register2) { |
417 | 0 | MCSymbol *Label = EmitCFICommon(); |
418 | 0 | MCCFIInstruction Instruction = |
419 | 0 | MCCFIInstruction::createRegister(Label, Register1, Register2); |
420 | 0 | MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo(); |
421 | 0 | CurFrame->Instructions.push_back(Instruction); |
422 | 0 | } |
423 | | |
424 | 0 | void MCStreamer::EmitCFIWindowSave() { |
425 | 0 | MCSymbol *Label = EmitCFICommon(); |
426 | 0 | MCCFIInstruction Instruction = |
427 | 0 | MCCFIInstruction::createWindowSave(Label); |
428 | 0 | MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo(); |
429 | 0 | CurFrame->Instructions.push_back(Instruction); |
430 | 0 | } |
431 | | |
432 | 0 | void MCStreamer::EnsureValidWinFrameInfo() { |
433 | 0 | const MCAsmInfo *MAI = Context.getAsmInfo(); |
434 | 0 | if (!MAI->usesWindowsCFI()) |
435 | 0 | report_fatal_error(".seh_* directives are not supported on this target"); |
436 | 0 | if (!CurrentWinFrameInfo || CurrentWinFrameInfo->End) |
437 | 0 | report_fatal_error("No open Win64 EH frame function!"); |
438 | 0 | } |
439 | | |
440 | 0 | void MCStreamer::EmitWinCFIStartProc(const MCSymbol *Symbol) { |
441 | 0 | const MCAsmInfo *MAI = Context.getAsmInfo(); |
442 | 0 | if (!MAI->usesWindowsCFI()) |
443 | 0 | report_fatal_error(".seh_* directives are not supported on this target"); |
444 | 0 | if (CurrentWinFrameInfo && !CurrentWinFrameInfo->End) |
445 | 0 | report_fatal_error("Starting a function before ending the previous one!"); |
446 | | |
447 | 0 | MCSymbol *StartProc = getContext().createTempSymbol(); |
448 | 0 | EmitLabel(StartProc); |
449 | |
|
450 | 0 | WinFrameInfos.push_back(new WinEH::FrameInfo(Symbol, StartProc)); |
451 | 0 | CurrentWinFrameInfo = WinFrameInfos.back(); |
452 | 0 | } |
453 | | |
454 | 0 | void MCStreamer::EmitWinCFIEndProc() { |
455 | 0 | EnsureValidWinFrameInfo(); |
456 | 0 | if (CurrentWinFrameInfo->ChainedParent) |
457 | 0 | report_fatal_error("Not all chained regions terminated!"); |
458 | | |
459 | 0 | MCSymbol *Label = getContext().createTempSymbol(); |
460 | 0 | EmitLabel(Label); |
461 | 0 | CurrentWinFrameInfo->End = Label; |
462 | 0 | } |
463 | | |
464 | 0 | void MCStreamer::EmitWinCFIStartChained() { |
465 | 0 | EnsureValidWinFrameInfo(); |
466 | |
|
467 | 0 | MCSymbol *StartProc = getContext().createTempSymbol(); |
468 | 0 | EmitLabel(StartProc); |
469 | |
|
470 | 0 | WinFrameInfos.push_back(new WinEH::FrameInfo(CurrentWinFrameInfo->Function, |
471 | 0 | StartProc, CurrentWinFrameInfo)); |
472 | 0 | CurrentWinFrameInfo = WinFrameInfos.back(); |
473 | 0 | } |
474 | | |
475 | 0 | void MCStreamer::EmitWinCFIEndChained() { |
476 | 0 | EnsureValidWinFrameInfo(); |
477 | 0 | if (!CurrentWinFrameInfo->ChainedParent) |
478 | 0 | report_fatal_error("End of a chained region outside a chained region!"); |
479 | | |
480 | 0 | MCSymbol *Label = getContext().createTempSymbol(); |
481 | 0 | EmitLabel(Label); |
482 | |
|
483 | 0 | CurrentWinFrameInfo->End = Label; |
484 | 0 | CurrentWinFrameInfo = |
485 | 0 | const_cast<WinEH::FrameInfo *>(CurrentWinFrameInfo->ChainedParent); |
486 | 0 | } |
487 | | |
488 | | void MCStreamer::EmitWinEHHandler(const MCSymbol *Sym, bool Unwind, |
489 | 0 | bool Except) { |
490 | 0 | EnsureValidWinFrameInfo(); |
491 | 0 | if (CurrentWinFrameInfo->ChainedParent) |
492 | 0 | report_fatal_error("Chained unwind areas can't have handlers!"); |
493 | 0 | CurrentWinFrameInfo->ExceptionHandler = Sym; |
494 | 0 | if (!Except && !Unwind) |
495 | 0 | report_fatal_error("Don't know what kind of handler this is!"); |
496 | 0 | if (Unwind) |
497 | 0 | CurrentWinFrameInfo->HandlesUnwind = true; |
498 | 0 | if (Except) |
499 | 0 | CurrentWinFrameInfo->HandlesExceptions = true; |
500 | 0 | } |
501 | | |
502 | 0 | void MCStreamer::EmitWinEHHandlerData() { |
503 | 0 | EnsureValidWinFrameInfo(); |
504 | 0 | if (CurrentWinFrameInfo->ChainedParent) |
505 | 0 | report_fatal_error("Chained unwind areas can't have handlers!"); |
506 | 0 | } |
507 | | |
508 | 0 | void MCStreamer::EmitSyntaxDirective() {} |
509 | | |
510 | 0 | void MCStreamer::EmitWinCFIPushReg(unsigned Register) { |
511 | 0 | EnsureValidWinFrameInfo(); |
512 | |
|
513 | 0 | MCSymbol *Label = getContext().createTempSymbol(); |
514 | 0 | EmitLabel(Label); |
515 | |
|
516 | 0 | WinEH::Instruction Inst = Win64EH::Instruction::PushNonVol(Label, Register); |
517 | 0 | CurrentWinFrameInfo->Instructions.push_back(Inst); |
518 | 0 | } |
519 | | |
520 | 0 | void MCStreamer::EmitWinCFISetFrame(unsigned Register, unsigned Offset) { |
521 | 0 | EnsureValidWinFrameInfo(); |
522 | 0 | if (CurrentWinFrameInfo->LastFrameInst >= 0) |
523 | 0 | report_fatal_error("Frame register and offset already specified!"); |
524 | 0 | if (Offset & 0x0F) |
525 | 0 | report_fatal_error("Misaligned frame pointer offset!"); |
526 | 0 | if (Offset > 240) |
527 | 0 | report_fatal_error("Frame offset must be less than or equal to 240!"); |
528 | | |
529 | 0 | MCSymbol *Label = getContext().createTempSymbol(); |
530 | 0 | EmitLabel(Label); |
531 | |
|
532 | 0 | WinEH::Instruction Inst = |
533 | 0 | Win64EH::Instruction::SetFPReg(Label, Register, Offset); |
534 | 0 | CurrentWinFrameInfo->LastFrameInst = CurrentWinFrameInfo->Instructions.size(); |
535 | 0 | CurrentWinFrameInfo->Instructions.push_back(Inst); |
536 | 0 | } |
537 | | |
538 | 0 | void MCStreamer::EmitWinCFIAllocStack(unsigned Size) { |
539 | 0 | EnsureValidWinFrameInfo(); |
540 | 0 | if (Size == 0) |
541 | 0 | report_fatal_error("Allocation size must be non-zero!"); |
542 | 0 | if (Size & 7) |
543 | 0 | report_fatal_error("Misaligned stack allocation!"); |
544 | | |
545 | 0 | MCSymbol *Label = getContext().createTempSymbol(); |
546 | 0 | EmitLabel(Label); |
547 | |
|
548 | 0 | WinEH::Instruction Inst = Win64EH::Instruction::Alloc(Label, Size); |
549 | 0 | CurrentWinFrameInfo->Instructions.push_back(Inst); |
550 | 0 | } |
551 | | |
552 | 0 | void MCStreamer::EmitWinCFISaveReg(unsigned Register, unsigned Offset) { |
553 | 0 | EnsureValidWinFrameInfo(); |
554 | 0 | if (Offset & 7) |
555 | 0 | report_fatal_error("Misaligned saved register offset!"); |
556 | | |
557 | 0 | MCSymbol *Label = getContext().createTempSymbol(); |
558 | 0 | EmitLabel(Label); |
559 | |
|
560 | 0 | WinEH::Instruction Inst = |
561 | 0 | Win64EH::Instruction::SaveNonVol(Label, Register, Offset); |
562 | 0 | CurrentWinFrameInfo->Instructions.push_back(Inst); |
563 | 0 | } |
564 | | |
565 | 0 | void MCStreamer::EmitWinCFISaveXMM(unsigned Register, unsigned Offset) { |
566 | 0 | EnsureValidWinFrameInfo(); |
567 | 0 | if (Offset & 0x0F) |
568 | 0 | report_fatal_error("Misaligned saved vector register offset!"); |
569 | | |
570 | 0 | MCSymbol *Label = getContext().createTempSymbol(); |
571 | 0 | EmitLabel(Label); |
572 | |
|
573 | 0 | WinEH::Instruction Inst = |
574 | 0 | Win64EH::Instruction::SaveXMM(Label, Register, Offset); |
575 | 0 | CurrentWinFrameInfo->Instructions.push_back(Inst); |
576 | 0 | } |
577 | | |
578 | 0 | void MCStreamer::EmitWinCFIPushFrame(bool Code) { |
579 | 0 | EnsureValidWinFrameInfo(); |
580 | 0 | if (CurrentWinFrameInfo->Instructions.size() > 0) |
581 | 0 | report_fatal_error("If present, PushMachFrame must be the first UOP"); |
582 | | |
583 | 0 | MCSymbol *Label = getContext().createTempSymbol(); |
584 | 0 | EmitLabel(Label); |
585 | |
|
586 | 0 | WinEH::Instruction Inst = Win64EH::Instruction::PushMachFrame(Label, Code); |
587 | 0 | CurrentWinFrameInfo->Instructions.push_back(Inst); |
588 | 0 | } |
589 | | |
590 | 0 | void MCStreamer::EmitWinCFIEndProlog() { |
591 | 0 | EnsureValidWinFrameInfo(); |
592 | |
|
593 | 0 | MCSymbol *Label = getContext().createTempSymbol(); |
594 | 0 | EmitLabel(Label); |
595 | |
|
596 | 0 | CurrentWinFrameInfo->PrologEnd = Label; |
597 | 0 | } |
598 | | |
599 | 0 | void MCStreamer::EmitCOFFSafeSEH(MCSymbol const *Symbol) { |
600 | 0 | } |
601 | | |
602 | 0 | void MCStreamer::EmitCOFFSectionIndex(MCSymbol const *Symbol) { |
603 | 0 | } |
604 | | |
605 | 0 | void MCStreamer::EmitCOFFSecRel32(MCSymbol const *Symbol) { |
606 | 0 | } |
607 | | |
608 | | /// EmitRawText - If this file is backed by an assembly streamer, this dumps |
609 | | /// the specified string in the output .s file. This capability is |
610 | | /// indicated by the hasRawTextSupport() predicate. |
611 | 0 | void MCStreamer::EmitRawTextImpl(StringRef String) { |
612 | 0 | errs() << "EmitRawText called on an MCStreamer that doesn't support it, " |
613 | 0 | " something must not be fully mc'ized\n"; |
614 | 0 | abort(); |
615 | 0 | } |
616 | | |
617 | 0 | void MCStreamer::EmitRawText(const Twine &T) { |
618 | 0 | SmallString<128> Str; |
619 | 0 | EmitRawTextImpl(T.toStringRef(Str)); |
620 | 0 | } |
621 | | |
622 | 0 | void MCStreamer::EmitWindowsUnwindTables() { |
623 | 0 | } |
624 | | |
625 | 79.4k | unsigned int MCStreamer::Finish() { |
626 | 79.4k | if (!DwarfFrameInfos.empty() && !DwarfFrameInfos.back().End) |
627 | 0 | report_fatal_error("Unfinished frame!"); |
628 | | |
629 | 79.4k | MCTargetStreamer *TS = getTargetStreamer(); |
630 | 79.4k | if (TS) |
631 | 52.2k | TS->finish(); |
632 | | |
633 | 79.4k | return FinishImpl(); |
634 | 79.4k | } |
635 | | |
636 | 1.14M | bool MCStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) { |
637 | 1.14M | visitUsedExpr(*Value); |
638 | 1.14M | bool valid; |
639 | 1.14M | Symbol->setVariableValue(Value, valid); |
640 | 1.14M | if (!valid) |
641 | 4.74k | return false; |
642 | | |
643 | 1.14M | MCTargetStreamer *TS = getTargetStreamer(); |
644 | 1.14M | if (TS) |
645 | 565k | TS->emitAssignment(Symbol, Value); |
646 | | |
647 | 1.14M | return true; |
648 | 1.14M | } |
649 | | |
650 | 0 | void MCStreamer::visitUsedSymbol(const MCSymbol &Sym) { |
651 | 0 | } |
652 | | |
653 | 6.52M | void MCStreamer::visitUsedExpr(const MCExpr &Expr) { |
654 | 6.52M | switch (Expr.getKind()) { |
655 | 1.18k | case MCExpr::Target: |
656 | 1.18k | cast<MCTargetExpr>(Expr).visitUsedExpr(*this); |
657 | 1.18k | break; |
658 | | |
659 | 1.53M | case MCExpr::Constant: |
660 | 1.53M | break; |
661 | | |
662 | 1.69M | case MCExpr::Binary: { |
663 | 1.69M | const MCBinaryExpr &BE = cast<MCBinaryExpr>(Expr); |
664 | 1.69M | visitUsedExpr(*BE.getLHS()); |
665 | 1.69M | visitUsedExpr(*BE.getRHS()); |
666 | 1.69M | break; |
667 | 0 | } |
668 | | |
669 | 2.61M | case MCExpr::SymbolRef: |
670 | 2.61M | visitUsedSymbol(cast<MCSymbolRefExpr>(Expr).getSymbol()); |
671 | 2.61M | break; |
672 | | |
673 | 676k | case MCExpr::Unary: |
674 | 676k | visitUsedExpr(*cast<MCUnaryExpr>(Expr).getSubExpr()); |
675 | 676k | break; |
676 | 6.52M | } |
677 | 6.52M | } |
678 | | |
679 | | void MCStreamer::EmitInstruction(MCInst &Inst, |
680 | | const MCSubtargetInfo &STI, |
681 | 388k | unsigned int &KsError) { |
682 | | // Scan for values. |
683 | 1.63M | for (unsigned i = Inst.getNumOperands(); i--;) |
684 | 1.24M | if (Inst.getOperand(i).isExpr()) |
685 | 175k | visitUsedExpr(*Inst.getOperand(i).getExpr()); |
686 | 388k | } |
687 | | |
688 | | void MCStreamer::emitAbsoluteSymbolDiff(const MCSymbol *Hi, const MCSymbol *Lo, |
689 | 0 | unsigned Size) { |
690 | | // Get the Hi-Lo expression. |
691 | 0 | const MCExpr *Diff = |
692 | 0 | MCBinaryExpr::createSub(MCSymbolRefExpr::create(Hi, Context), |
693 | 0 | MCSymbolRefExpr::create(Lo, Context), Context); |
694 | |
|
695 | 0 | const MCAsmInfo *MAI = Context.getAsmInfo(); |
696 | 0 | if (!MAI->doesSetDirectiveSuppressesReloc()) { |
697 | 0 | EmitValue(Diff, Size); |
698 | 0 | return; |
699 | 0 | } |
700 | | |
701 | | // Otherwise, emit with .set (aka assignment). |
702 | 0 | MCSymbol *SetLabel = Context.createTempSymbol("set", true); |
703 | 0 | EmitAssignment(SetLabel, Diff); |
704 | 0 | EmitSymbolValue(SetLabel, Size); |
705 | 0 | } |
706 | | |
707 | 0 | void MCStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) {} |
708 | 0 | void MCStreamer::EmitThumbFunc(MCSymbol *Func) {} |
709 | 0 | void MCStreamer::EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {} |
710 | 0 | void MCStreamer::BeginCOFFSymbolDef(const MCSymbol *Symbol) {} |
711 | 0 | void MCStreamer::EndCOFFSymbolDef() {} |
712 | 0 | void MCStreamer::EmitFileDirective(StringRef Filename) {} |
713 | 0 | void MCStreamer::EmitCOFFSymbolStorageClass(int StorageClass) {} |
714 | 0 | void MCStreamer::EmitCOFFSymbolType(int Type) {} |
715 | 0 | void MCStreamer::emitELFSize(MCSymbolELF *Symbol, const MCExpr *Value) {} |
716 | | void MCStreamer::EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size, |
717 | 0 | unsigned ByteAlignment) {} |
718 | | void MCStreamer::EmitTBSSSymbol(MCSection *Section, MCSymbol *Symbol, |
719 | 0 | uint64_t Size, unsigned ByteAlignment) {} |
720 | 0 | void MCStreamer::ChangeSection(MCSection *, const MCExpr *) {} |
721 | 0 | void MCStreamer::EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) {} |
722 | 0 | void MCStreamer::EmitBytes(StringRef Data) {} |
723 | 1.13M | void MCStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size, SMLoc Loc) { |
724 | 1.13M | visitUsedExpr(*Value); |
725 | 1.13M | } |
726 | 0 | void MCStreamer::EmitULEB128Value(const MCExpr *Value) {} |
727 | 0 | void MCStreamer::EmitSLEB128Value(const MCExpr *Value) {} |
728 | | void MCStreamer::EmitValueToAlignment(unsigned ByteAlignment, int64_t Value, |
729 | | unsigned ValueSize, |
730 | 0 | unsigned MaxBytesToEmit) {} |
731 | | void MCStreamer::EmitCodeAlignment(unsigned ByteAlignment, |
732 | 0 | unsigned MaxBytesToEmit) {} |
733 | 0 | void MCStreamer::emitValueToOffset(const MCExpr *Offset, unsigned char Value) {} |
734 | 0 | void MCStreamer::EmitBundleAlignMode(unsigned AlignPow2) {} |
735 | 0 | void MCStreamer::EmitBundleLock(bool AlignToEnd) {} |
736 | 0 | unsigned int MCStreamer::FinishImpl() { return 0; } |
737 | 0 | void MCStreamer::EmitBundleUnlock() {} |
738 | | |
739 | 231k | void MCStreamer::SwitchSection(MCSection *Section, const MCExpr *Subsection) { |
740 | 231k | assert(Section && "Cannot switch to a null section!"); |
741 | 231k | MCSectionSubPair curSection = SectionStack.back().first; |
742 | 231k | SectionStack.back().second = curSection; |
743 | 231k | if (MCSectionSubPair(Section, Subsection) != curSection) { |
744 | 202k | ChangeSection(Section, Subsection); |
745 | 202k | SectionStack.back().first = MCSectionSubPair(Section, Subsection); |
746 | 202k | assert(!Section->hasEnded() && "Section already ended"); |
747 | 202k | MCSymbol *Sym = Section->getBeginSymbol(); |
748 | 202k | if (Sym && !Sym->isInSection()) |
749 | 178k | EmitLabel(Sym); |
750 | 202k | } |
751 | 231k | } |
752 | | |
753 | 0 | MCSymbol *MCStreamer::endSection(MCSection *Section) { |
754 | | // TODO: keep track of the last subsection so that this symbol appears in the |
755 | | // correct place. |
756 | 0 | MCSymbol *Sym = Section->getEndSymbol(Context); |
757 | 0 | if (Sym->isInSection()) |
758 | 0 | return Sym; |
759 | | |
760 | 0 | SwitchSection(Section); |
761 | 0 | EmitLabel(Sym); |
762 | 0 | return Sym; |
763 | 0 | } |