MCStreamer.cpp revision c2d3022aa6104a21f4368c522ccbf9a4d282b7c6
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/MCAsmInfo.h"
11#include "llvm/MC/MCContext.h"
12#include "llvm/MC/MCStreamer.h"
13#include "llvm/MC/MCExpr.h"
14#include "llvm/MC/MCObjectWriter.h"
15#include "llvm/MC/MCSymbol.h"
16#include "llvm/Support/ErrorHandling.h"
17#include "llvm/Support/raw_ostream.h"
18#include "llvm/ADT/SmallString.h"
19#include "llvm/ADT/Twine.h"
20#include <cstdlib>
21using namespace llvm;
22
23MCStreamer::MCStreamer(MCContext &Ctx) : Context(Ctx), EmitEHFrame(true),
24                                         EmitDebugFrame(false),
25                                         CurrentW64UnwindInfo(0) {
26  const MCSection *section = NULL;
27  SectionStack.push_back(std::make_pair(section, section));
28}
29
30MCStreamer::~MCStreamer() {
31}
32
33const MCExpr *MCStreamer::BuildSymbolDiff(MCContext &Context,
34                                          const MCSymbol *A,
35                                          const MCSymbol *B) {
36  MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
37  const MCExpr *ARef =
38    MCSymbolRefExpr::Create(A, Variant, Context);
39  const MCExpr *BRef =
40    MCSymbolRefExpr::Create(B, Variant, Context);
41  const MCExpr *AddrDelta =
42    MCBinaryExpr::Create(MCBinaryExpr::Sub, ARef, BRef, Context);
43  return AddrDelta;
44}
45
46const MCExpr *MCStreamer::ForceExpAbs(const MCExpr* Expr) {
47  if (Context.getAsmInfo().hasAggressiveSymbolFolding() ||
48      isa<MCSymbolRefExpr>(Expr))
49    return Expr;
50
51  MCSymbol *ABS = Context.CreateTempSymbol();
52  EmitAssignment(ABS, Expr);
53  return MCSymbolRefExpr::Create(ABS, Context);
54}
55
56raw_ostream &MCStreamer::GetCommentOS() {
57  // By default, discard comments.
58  return nulls();
59}
60
61void MCStreamer::EmitDwarfSetLineAddr(int64_t LineDelta,
62                                      const MCSymbol *Label, int PointerSize) {
63  // emit the sequence to set the address
64  EmitIntValue(dwarf::DW_LNS_extended_op, 1);
65  EmitULEB128IntValue(PointerSize + 1);
66  EmitIntValue(dwarf::DW_LNE_set_address, 1);
67  EmitSymbolValue(Label, PointerSize);
68
69  // emit the sequence for the LineDelta (from 1) and a zero address delta.
70  MCDwarfLineAddr::Emit(this, LineDelta, 0);
71}
72
73/// EmitIntValue - Special case of EmitValue that avoids the client having to
74/// pass in a MCExpr for constant integers.
75void MCStreamer::EmitIntValue(uint64_t Value, unsigned Size,
76                              unsigned AddrSpace) {
77  assert(Size <= 8 && "Invalid size");
78  assert((isUIntN(8 * Size, Value) || isIntN(8 * Size, Value)) &&
79         "Invalid size");
80  char buf[8];
81  // FIXME: Endianness assumption.
82  for (unsigned i = 0; i != Size; ++i)
83    buf[i] = uint8_t(Value >> (i * 8));
84  EmitBytes(StringRef(buf, Size), AddrSpace);
85}
86
87/// EmitULEB128Value - Special case of EmitULEB128Value that avoids the
88/// client having to pass in a MCExpr for constant integers.
89void MCStreamer::EmitULEB128IntValue(uint64_t Value, unsigned AddrSpace) {
90  SmallString<32> Tmp;
91  raw_svector_ostream OSE(Tmp);
92  MCObjectWriter::EncodeULEB128(Value, OSE);
93  EmitBytes(OSE.str(), AddrSpace);
94}
95
96/// EmitSLEB128Value - Special case of EmitSLEB128Value that avoids the
97/// client having to pass in a MCExpr for constant integers.
98void MCStreamer::EmitSLEB128IntValue(int64_t Value, unsigned AddrSpace) {
99  SmallString<32> Tmp;
100  raw_svector_ostream OSE(Tmp);
101  MCObjectWriter::EncodeSLEB128(Value, OSE);
102  EmitBytes(OSE.str(), AddrSpace);
103}
104
105void MCStreamer::EmitAbsValue(const MCExpr *Value, unsigned Size,
106                              unsigned AddrSpace) {
107  const MCExpr *ABS = ForceExpAbs(Value);
108  EmitValue(ABS, Size, AddrSpace);
109}
110
111
112void MCStreamer::EmitValue(const MCExpr *Value, unsigned Size,
113                           unsigned AddrSpace) {
114  EmitValueImpl(Value, Size, AddrSpace);
115}
116
117void MCStreamer::EmitSymbolValue(const MCSymbol *Sym, unsigned Size,
118                                  unsigned AddrSpace) {
119  EmitValueImpl(MCSymbolRefExpr::Create(Sym, getContext()), Size,
120                AddrSpace);
121}
122
123void MCStreamer::EmitGPRel32Value(const MCExpr *Value) {
124  report_fatal_error("unsupported directive in streamer");
125}
126
127/// EmitFill - Emit NumBytes bytes worth of the value specified by
128/// FillValue.  This implements directives such as '.space'.
129void MCStreamer::EmitFill(uint64_t NumBytes, uint8_t FillValue,
130                          unsigned AddrSpace) {
131  const MCExpr *E = MCConstantExpr::Create(FillValue, getContext());
132  for (uint64_t i = 0, e = NumBytes; i != e; ++i)
133    EmitValue(E, 1, AddrSpace);
134}
135
136bool MCStreamer::EmitDwarfFileDirective(unsigned FileNo,
137                                        StringRef Filename) {
138  return getContext().GetDwarfFile(Filename, FileNo) == 0;
139}
140
141void MCStreamer::EmitDwarfLocDirective(unsigned FileNo, unsigned Line,
142                                       unsigned Column, unsigned Flags,
143                                       unsigned Isa,
144                                       unsigned Discriminator,
145                                       StringRef FileName) {
146  getContext().setCurrentDwarfLoc(FileNo, Line, Column, Flags, Isa,
147                                  Discriminator);
148}
149
150MCDwarfFrameInfo *MCStreamer::getCurrentFrameInfo() {
151  if (FrameInfos.empty())
152    return NULL;
153  return &FrameInfos.back();
154}
155
156void MCStreamer::EnsureValidFrame() {
157  MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo();
158  if (!CurFrame || CurFrame->End)
159    report_fatal_error("No open frame");
160}
161
162void MCStreamer::EmitEHSymAttributes(const MCSymbol *Symbol,
163                                     MCSymbol *EHSymbol) {
164}
165
166void MCStreamer::EmitLabel(MCSymbol *Symbol) {
167  assert(!Symbol->isVariable() && "Cannot emit a variable symbol!");
168  assert(getCurrentSection() && "Cannot emit before setting section!");
169  Symbol->setSection(*getCurrentSection());
170
171  StringRef Prefix = getContext().getAsmInfo().getPrivateGlobalPrefix();
172  if (!Symbol->getName().startswith(Prefix))
173    LastNonPrivate = Symbol;
174}
175
176void MCStreamer::EmitCFISections(bool EH, bool Debug) {
177  assert(EH || Debug);
178  EmitEHFrame = EH;
179  EmitDebugFrame = Debug;
180}
181
182void MCStreamer::EmitCFIStartProc() {
183  MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo();
184  if (CurFrame && !CurFrame->End)
185    report_fatal_error("Starting a frame before finishing the previous one!");
186  MCDwarfFrameInfo Frame;
187  Frame.Begin = getContext().CreateTempSymbol();
188  Frame.Function = LastNonPrivate;
189  EmitLabel(Frame.Begin);
190  FrameInfos.push_back(Frame);
191}
192
193void MCStreamer::EmitCFIEndProc() {
194  EnsureValidFrame();
195  MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo();
196  CurFrame->End = getContext().CreateTempSymbol();
197  EmitLabel(CurFrame->End);
198}
199
200void MCStreamer::EmitCFIDefCfa(int64_t Register, int64_t Offset) {
201  EnsureValidFrame();
202  MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo();
203  MCSymbol *Label = getContext().CreateTempSymbol();
204  EmitLabel(Label);
205  MachineLocation Dest(MachineLocation::VirtualFP);
206  MachineLocation Source(Register, -Offset);
207  MCCFIInstruction Instruction(Label, Dest, Source);
208  CurFrame->Instructions.push_back(Instruction);
209}
210
211void MCStreamer::EmitCFIDefCfaOffset(int64_t Offset) {
212  EnsureValidFrame();
213  MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo();
214  MCSymbol *Label = getContext().CreateTempSymbol();
215  EmitLabel(Label);
216  MachineLocation Dest(MachineLocation::VirtualFP);
217  MachineLocation Source(MachineLocation::VirtualFP, -Offset);
218  MCCFIInstruction Instruction(Label, Dest, Source);
219  CurFrame->Instructions.push_back(Instruction);
220}
221
222void MCStreamer::EmitCFIAdjustCfaOffset(int64_t Adjustment) {
223  EnsureValidFrame();
224  MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo();
225  MCSymbol *Label = getContext().CreateTempSymbol();
226  EmitLabel(Label);
227  MachineLocation Dest(MachineLocation::VirtualFP);
228  MachineLocation Source(MachineLocation::VirtualFP, Adjustment);
229  MCCFIInstruction Instruction(MCCFIInstruction::RelMove, Label, Dest, Source);
230  CurFrame->Instructions.push_back(Instruction);
231}
232
233void MCStreamer::EmitCFIDefCfaRegister(int64_t Register) {
234  EnsureValidFrame();
235  MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo();
236  MCSymbol *Label = getContext().CreateTempSymbol();
237  EmitLabel(Label);
238  MachineLocation Dest(Register);
239  MachineLocation Source(MachineLocation::VirtualFP);
240  MCCFIInstruction Instruction(Label, Dest, Source);
241  CurFrame->Instructions.push_back(Instruction);
242}
243
244void MCStreamer::EmitCFIOffset(int64_t Register, int64_t Offset) {
245  EnsureValidFrame();
246  MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo();
247  MCSymbol *Label = getContext().CreateTempSymbol();
248  EmitLabel(Label);
249  MachineLocation Dest(Register, Offset);
250  MachineLocation Source(Register, Offset);
251  MCCFIInstruction Instruction(Label, Dest, Source);
252  CurFrame->Instructions.push_back(Instruction);
253}
254
255void MCStreamer::EmitCFIRelOffset(int64_t Register, int64_t Offset) {
256  EnsureValidFrame();
257  MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo();
258  MCSymbol *Label = getContext().CreateTempSymbol();
259  EmitLabel(Label);
260  MachineLocation Dest(Register, Offset);
261  MachineLocation Source(Register, Offset);
262  MCCFIInstruction Instruction(MCCFIInstruction::RelMove, Label, Dest, Source);
263  CurFrame->Instructions.push_back(Instruction);
264}
265
266void MCStreamer::EmitCFIPersonality(const MCSymbol *Sym,
267                                    unsigned Encoding) {
268  EnsureValidFrame();
269  MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo();
270  CurFrame->Personality = Sym;
271  CurFrame->PersonalityEncoding = Encoding;
272}
273
274void MCStreamer::EmitCFILsda(const MCSymbol *Sym, unsigned Encoding) {
275  EnsureValidFrame();
276  MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo();
277  CurFrame->Lsda = Sym;
278  CurFrame->LsdaEncoding = Encoding;
279}
280
281void MCStreamer::EmitCFIRememberState() {
282  EnsureValidFrame();
283  MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo();
284  MCSymbol *Label = getContext().CreateTempSymbol();
285  EmitLabel(Label);
286  MCCFIInstruction Instruction(MCCFIInstruction::Remember, Label);
287  CurFrame->Instructions.push_back(Instruction);
288}
289
290void MCStreamer::EmitCFIRestoreState() {
291  // FIXME: Error if there is no matching cfi_remember_state.
292  EnsureValidFrame();
293  MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo();
294  MCSymbol *Label = getContext().CreateTempSymbol();
295  EmitLabel(Label);
296  MCCFIInstruction Instruction(MCCFIInstruction::Restore, Label);
297  CurFrame->Instructions.push_back(Instruction);
298}
299
300void MCStreamer::EmitCFISameValue(int64_t Register) {
301  EnsureValidFrame();
302  MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo();
303  MCSymbol *Label = getContext().CreateTempSymbol();
304  EmitLabel(Label);
305  MCCFIInstruction Instruction(MCCFIInstruction::SameValue, Label, Register);
306  CurFrame->Instructions.push_back(Instruction);
307}
308
309void MCStreamer::setCurrentW64UnwindInfo(MCWin64EHUnwindInfo *Frame) {
310  W64UnwindInfos.push_back(Frame);
311  CurrentW64UnwindInfo = W64UnwindInfos.back();
312}
313
314void MCStreamer::EnsureValidW64UnwindInfo() {
315  MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo;
316  if (!CurFrame || CurFrame->End)
317    report_fatal_error("No open Win64 EH frame function!");
318}
319
320void MCStreamer::EmitWin64EHStartProc(const MCSymbol *Symbol) {
321  MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo;
322  if (CurFrame && !CurFrame->End)
323    report_fatal_error("Starting a function before ending the previous one!");
324  MCWin64EHUnwindInfo *Frame = new (getContext()) MCWin64EHUnwindInfo;
325  Frame->Begin = getContext().CreateTempSymbol();
326  Frame->Function = Symbol;
327  EmitLabel(Frame->Begin);
328  setCurrentW64UnwindInfo(Frame);
329}
330
331void MCStreamer::EmitWin64EHEndProc() {
332  EnsureValidW64UnwindInfo();
333  MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo;
334  if (CurFrame->ChainedParent)
335    report_fatal_error("Not all chained regions terminated!");
336  CurFrame->End = getContext().CreateTempSymbol();
337  EmitLabel(CurFrame->End);
338}
339
340void MCStreamer::EmitWin64EHStartChained() {
341  EnsureValidW64UnwindInfo();
342  MCWin64EHUnwindInfo *Frame = new (getContext()) MCWin64EHUnwindInfo;
343  MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo;
344  Frame->Begin = getContext().CreateTempSymbol();
345  Frame->Function = CurFrame->Function;
346  Frame->ChainedParent = CurFrame;
347  EmitLabel(Frame->Begin);
348  setCurrentW64UnwindInfo(Frame);
349}
350
351void MCStreamer::EmitWin64EHEndChained() {
352  EnsureValidW64UnwindInfo();
353  MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo;
354  if (!CurFrame->ChainedParent)
355    report_fatal_error("End of a chained region outside a chained region!");
356  CurFrame->End = getContext().CreateTempSymbol();
357  EmitLabel(CurFrame->End);
358  CurrentW64UnwindInfo = CurFrame->ChainedParent;
359}
360
361void MCStreamer::EmitWin64EHHandler(const MCSymbol *Sym, bool Unwind,
362                                    bool Except) {
363  EnsureValidW64UnwindInfo();
364  MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo;
365  if (CurFrame->ChainedParent)
366    report_fatal_error("Chained unwind areas can't have handlers!");
367  CurFrame->ExceptionHandler = Sym;
368  if (!Except && !Unwind)
369    report_fatal_error("Don't know what kind of handler this is!");
370  if (Unwind)
371    CurFrame->HandlesUnwind = true;
372  if (Except)
373    CurFrame->HandlesExceptions = true;
374}
375
376void MCStreamer::EmitWin64EHHandlerData() {
377  EnsureValidW64UnwindInfo();
378  MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo;
379  if (CurFrame->ChainedParent)
380    report_fatal_error("Chained unwind areas can't have handlers!");
381}
382
383void MCStreamer::EmitWin64EHPushReg(unsigned Register) {
384  EnsureValidW64UnwindInfo();
385  MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo;
386  MCWin64EHInstruction Inst(Win64EH::UOP_PushNonVol, Register);
387  CurFrame->Instructions.push_back(Inst);
388}
389
390void MCStreamer::EmitWin64EHSetFrame(unsigned Register, unsigned Offset) {
391  EnsureValidW64UnwindInfo();
392  MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo;
393  if (CurFrame->LastFrameInst >= 0)
394    report_fatal_error("Frame register and offset already specified!");
395  if (Offset & 0x0F)
396    report_fatal_error("Misaligned frame pointer offset!");
397  MCWin64EHInstruction Inst(Win64EH::UOP_SetFPReg, Register, Offset);
398  CurFrame->LastFrameInst = CurFrame->Instructions.size();
399  CurFrame->Instructions.push_back(Inst);
400}
401
402void MCStreamer::EmitWin64EHAllocStack(unsigned Size) {
403  EnsureValidW64UnwindInfo();
404  if (Size & 7)
405    report_fatal_error("Misaligned stack allocation!");
406  MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo;
407  MCWin64EHInstruction Inst(Size);
408  CurFrame->Instructions.push_back(Inst);
409}
410
411void MCStreamer::EmitWin64EHSaveReg(unsigned Register, unsigned Offset) {
412  EnsureValidW64UnwindInfo();
413  if (Offset & 7)
414    report_fatal_error("Misaligned saved register offset!");
415  MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo;
416  MCWin64EHInstruction Inst(
417     Offset > 512*1024-8 ? Win64EH::UOP_SaveNonVolBig : Win64EH::UOP_SaveNonVol,
418                            Register, Offset);
419  CurFrame->Instructions.push_back(Inst);
420}
421
422void MCStreamer::EmitWin64EHSaveXMM(unsigned Register, unsigned Offset) {
423  EnsureValidW64UnwindInfo();
424  if (Offset & 0x0F)
425    report_fatal_error("Misaligned saved vector register offset!");
426  MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo;
427  MCWin64EHInstruction Inst(
428    Offset > 512*1024-16 ? Win64EH::UOP_SaveXMM128Big : Win64EH::UOP_SaveXMM128,
429                            Register, Offset);
430  CurFrame->Instructions.push_back(Inst);
431}
432
433void MCStreamer::EmitWin64EHPushFrame(bool Code) {
434  EnsureValidW64UnwindInfo();
435  MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo;
436  if (CurFrame->Instructions.size() > 0)
437    report_fatal_error("If present, PushMachFrame must be the first UOP");
438  MCWin64EHInstruction Inst(Win64EH::UOP_PushMachFrame, Code);
439  CurFrame->Instructions.push_back(Inst);
440}
441
442void MCStreamer::EmitWin64EHEndProlog() {
443  EnsureValidW64UnwindInfo();
444  MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo;
445  CurFrame->PrologEnd = getContext().CreateTempSymbol();
446  EmitLabel(CurFrame->PrologEnd);
447}
448
449void MCStreamer::EmitFnStart() {
450  errs() << "Not implemented yet\n";
451  abort();
452}
453
454void MCStreamer::EmitFnEnd() {
455  errs() << "Not implemented yet\n";
456  abort();
457}
458
459void MCStreamer::EmitCantUnwind() {
460  errs() << "Not implemented yet\n";
461  abort();
462}
463
464void MCStreamer::EmitHandlerData() {
465  errs() << "Not implemented yet\n";
466  abort();
467}
468
469void MCStreamer::EmitPersonality(const MCSymbol *Personality) {
470  errs() << "Not implemented yet\n";
471  abort();
472}
473
474void MCStreamer::EmitSetFP(unsigned FpReg, unsigned SpReg, int64_t Offset) {
475  errs() << "Not implemented yet\n";
476  abort();
477}
478
479void MCStreamer::EmitPad(int64_t Offset) {
480  errs() << "Not implemented yet\n";
481  abort();
482}
483
484void MCStreamer::EmitRegSave(const SmallVectorImpl<unsigned> &RegList, bool) {
485  errs() << "Not implemented yet\n";
486  abort();
487}
488
489/// EmitRawText - If this file is backed by an assembly streamer, this dumps
490/// the specified string in the output .s file.  This capability is
491/// indicated by the hasRawTextSupport() predicate.
492void MCStreamer::EmitRawText(StringRef String) {
493  errs() << "EmitRawText called on an MCStreamer that doesn't support it, "
494  " something must not be fully mc'ized\n";
495  abort();
496}
497
498void MCStreamer::EmitRawText(const Twine &T) {
499  SmallString<128> Str;
500  T.toVector(Str);
501  EmitRawText(Str.str());
502}
503
504void MCStreamer::EmitFrames(bool usingCFI) {
505  if (!getNumFrameInfos())
506    return;
507
508  if (EmitEHFrame)
509    MCDwarfFrameEmitter::Emit(*this, usingCFI, true);
510
511  if (EmitDebugFrame)
512    MCDwarfFrameEmitter::Emit(*this, usingCFI, false);
513}
514
515void MCStreamer::EmitW64Tables() {
516  if (!getNumW64UnwindInfos())
517    return;
518
519  MCWin64EHUnwindEmitter::Emit(*this);
520}
521