MCObjectStreamer.cpp revision 4df4bccc71ea0477836db9a417d3da202c2baa09
1//===- lib/MC/MCObjectStreamer.cpp - Object File MCStreamer Interface -----===//
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/MCObjectStreamer.h"
11#include "llvm/ADT/STLExtras.h"
12#include "llvm/MC/MCAsmBackend.h"
13#include "llvm/MC/MCAsmInfo.h"
14#include "llvm/MC/MCAssembler.h"
15#include "llvm/MC/MCCodeEmitter.h"
16#include "llvm/MC/MCContext.h"
17#include "llvm/MC/MCDwarf.h"
18#include "llvm/MC/MCExpr.h"
19#include "llvm/MC/MCObjectWriter.h"
20#include "llvm/MC/MCSymbol.h"
21#include "llvm/Support/ErrorHandling.h"
22using namespace llvm;
23
24MCObjectStreamer::MCObjectStreamer(StreamerKind Kind, MCContext &Context,
25                                   MCAsmBackend &TAB, raw_ostream &OS,
26                                   MCCodeEmitter *Emitter_)
27    : MCStreamer(Kind, Context),
28      Assembler(new MCAssembler(Context, TAB, *Emitter_,
29                                *TAB.createObjectWriter(OS), OS)),
30      CurSectionData(0) {}
31
32MCObjectStreamer::MCObjectStreamer(StreamerKind Kind, MCContext &Context,
33                                   MCAsmBackend &TAB, raw_ostream &OS,
34                                   MCCodeEmitter *Emitter_,
35                                   MCAssembler *_Assembler)
36    : MCStreamer(Kind, Context), Assembler(_Assembler), CurSectionData(0) {}
37
38MCObjectStreamer::~MCObjectStreamer() {
39  delete &Assembler->getBackend();
40  delete &Assembler->getEmitter();
41  delete &Assembler->getWriter();
42  delete Assembler;
43}
44
45void MCObjectStreamer::reset() {
46  if (Assembler)
47    Assembler->reset();
48  CurSectionData = 0;
49  CurInsertionPoint = MCSectionData::iterator();
50  MCStreamer::reset();
51}
52
53MCFragment *MCObjectStreamer::getCurrentFragment() const {
54  assert(getCurrentSectionData() && "No current section!");
55
56  if (CurInsertionPoint != getCurrentSectionData()->getFragmentList().begin())
57    return prior(CurInsertionPoint);
58
59  return 0;
60}
61
62MCDataFragment *MCObjectStreamer::getOrCreateDataFragment() const {
63  MCDataFragment *F = dyn_cast_or_null<MCDataFragment>(getCurrentFragment());
64  // When bundling is enabled, we don't want to add data to a fragment that
65  // already has instructions (see MCELFStreamer::EmitInstToData for details)
66  if (!F || (Assembler->isBundlingEnabled() && F->hasInstructions())) {
67    F = new MCDataFragment();
68    insert(F);
69  }
70  return F;
71}
72
73const MCExpr *MCObjectStreamer::AddValueSymbols(const MCExpr *Value) {
74  switch (Value->getKind()) {
75  case MCExpr::Target:
76    cast<MCTargetExpr>(Value)->AddValueSymbols(Assembler);
77    break;
78
79  case MCExpr::Constant:
80    break;
81
82  case MCExpr::Binary: {
83    const MCBinaryExpr *BE = cast<MCBinaryExpr>(Value);
84    AddValueSymbols(BE->getLHS());
85    AddValueSymbols(BE->getRHS());
86    break;
87  }
88
89  case MCExpr::SymbolRef:
90    Assembler->getOrCreateSymbolData(cast<MCSymbolRefExpr>(Value)->getSymbol());
91    break;
92
93  case MCExpr::Unary:
94    AddValueSymbols(cast<MCUnaryExpr>(Value)->getSubExpr());
95    break;
96  }
97
98  return Value;
99}
100
101void MCObjectStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size,
102                                     unsigned AddrSpace) {
103  assert(AddrSpace == 0 && "Address space must be 0!");
104  MCDataFragment *DF = getOrCreateDataFragment();
105
106  MCLineEntry::Make(this, getCurrentSection().first);
107
108  // Avoid fixups when possible.
109  int64_t AbsValue;
110  if (AddValueSymbols(Value)->EvaluateAsAbsolute(AbsValue, getAssembler())) {
111    EmitIntValue(AbsValue, Size, AddrSpace);
112    return;
113  }
114  DF->getFixups().push_back(
115      MCFixup::Create(DF->getContents().size(), Value,
116                      MCFixup::getKindForSize(Size, false)));
117  DF->getContents().resize(DF->getContents().size() + Size, 0);
118}
119
120void MCObjectStreamer::EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) {
121  RecordProcStart(Frame);
122}
123
124void MCObjectStreamer::EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) {
125  RecordProcEnd(Frame);
126}
127
128void MCObjectStreamer::EmitLabel(MCSymbol *Symbol) {
129  MCStreamer::EmitLabel(Symbol);
130
131  MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol);
132
133  // FIXME: This is wasteful, we don't necessarily need to create a data
134  // fragment. Instead, we should mark the symbol as pointing into the data
135  // fragment if it exists, otherwise we should just queue the label and set its
136  // fragment pointer when we emit the next fragment.
137  MCDataFragment *F = getOrCreateDataFragment();
138  assert(!SD.getFragment() && "Unexpected fragment on symbol data!");
139  SD.setFragment(F);
140  SD.setOffset(F->getContents().size());
141}
142
143void MCObjectStreamer::EmitDebugLabel(MCSymbol *Symbol) {
144  EmitLabel(Symbol);
145}
146
147void MCObjectStreamer::EmitULEB128Value(const MCExpr *Value) {
148  int64_t IntValue;
149  if (Value->EvaluateAsAbsolute(IntValue, getAssembler())) {
150    EmitULEB128IntValue(IntValue);
151    return;
152  }
153  Value = ForceExpAbs(Value);
154  insert(new MCLEBFragment(*Value, false));
155}
156
157void MCObjectStreamer::EmitSLEB128Value(const MCExpr *Value) {
158  int64_t IntValue;
159  if (Value->EvaluateAsAbsolute(IntValue, getAssembler())) {
160    EmitSLEB128IntValue(IntValue);
161    return;
162  }
163  Value = ForceExpAbs(Value);
164  insert(new MCLEBFragment(*Value, true));
165}
166
167void MCObjectStreamer::EmitWeakReference(MCSymbol *Alias,
168                                         const MCSymbol *Symbol) {
169  report_fatal_error("This file format doesn't support weak aliases.");
170}
171
172void MCObjectStreamer::ChangeSection(const MCSection *Section,
173                                     const MCExpr *Subsection) {
174  assert(Section && "Cannot switch to a null section!");
175
176  CurSectionData = &getAssembler().getOrCreateSectionData(*Section);
177
178  int64_t IntSubsection = 0;
179  if (Subsection &&
180      !Subsection->EvaluateAsAbsolute(IntSubsection, getAssembler()))
181    report_fatal_error("Cannot evaluate subsection number");
182  if (IntSubsection < 0 || IntSubsection > 8192)
183    report_fatal_error("Subsection number out of range");
184  CurInsertionPoint =
185    CurSectionData->getSubsectionInsertionPoint(unsigned(IntSubsection));
186}
187
188void MCObjectStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) {
189  getAssembler().getOrCreateSymbolData(*Symbol);
190  Symbol->setVariableValue(AddValueSymbols(Value));
191}
192
193void MCObjectStreamer::EmitInstruction(const MCInst &Inst) {
194  // Scan for values.
195  for (unsigned i = Inst.getNumOperands(); i--; )
196    if (Inst.getOperand(i).isExpr())
197      AddValueSymbols(Inst.getOperand(i).getExpr());
198
199  MCSectionData *SD = getCurrentSectionData();
200  SD->setHasInstructions(true);
201
202  // Now that a machine instruction has been assembled into this section, make
203  // a line entry for any .loc directive that has been seen.
204  MCLineEntry::Make(this, getCurrentSection().first);
205
206  // If this instruction doesn't need relaxation, just emit it as data.
207  MCAssembler &Assembler = getAssembler();
208  if (!Assembler.getBackend().mayNeedRelaxation(Inst)) {
209    EmitInstToData(Inst);
210    return;
211  }
212
213  // Otherwise, relax and emit it as data if either:
214  // - The RelaxAll flag was passed
215  // - Bundling is enabled and this instruction is inside a bundle-locked
216  //   group. We want to emit all such instructions into the same data
217  //   fragment.
218  if (Assembler.getRelaxAll() ||
219      (Assembler.isBundlingEnabled() && SD->isBundleLocked())) {
220    MCInst Relaxed;
221    getAssembler().getBackend().relaxInstruction(Inst, Relaxed);
222    while (getAssembler().getBackend().mayNeedRelaxation(Relaxed))
223      getAssembler().getBackend().relaxInstruction(Relaxed, Relaxed);
224    EmitInstToData(Relaxed);
225    return;
226  }
227
228  // Otherwise emit to a separate fragment.
229  EmitInstToFragment(Inst);
230}
231
232void MCObjectStreamer::EmitInstToFragment(const MCInst &Inst) {
233  // Always create a new, separate fragment here, because its size can change
234  // during relaxation.
235  MCRelaxableFragment *IF = new MCRelaxableFragment(Inst);
236  insert(IF);
237
238  SmallString<128> Code;
239  raw_svector_ostream VecOS(Code);
240  getAssembler().getEmitter().EncodeInstruction(Inst, VecOS, IF->getFixups());
241  VecOS.flush();
242  IF->getContents().append(Code.begin(), Code.end());
243}
244
245#ifndef NDEBUG
246static const char *BundlingNotImplementedMsg =
247  "Aligned bundling is not implemented for this object format";
248#endif
249
250void MCObjectStreamer::EmitBundleAlignMode(unsigned AlignPow2) {
251  llvm_unreachable(BundlingNotImplementedMsg);
252}
253
254void MCObjectStreamer::EmitBundleLock(bool AlignToEnd) {
255  llvm_unreachable(BundlingNotImplementedMsg);
256}
257
258void MCObjectStreamer::EmitBundleUnlock() {
259  llvm_unreachable(BundlingNotImplementedMsg);
260}
261
262void MCObjectStreamer::EmitDwarfLocDirective(unsigned FileNo, unsigned Line,
263                                             unsigned Column, unsigned Flags,
264                                             unsigned Isa,
265                                             unsigned Discriminator,
266                                             StringRef FileName) {
267  // In case we see two .loc directives in a row, make sure the
268  // first one gets a line entry.
269  MCLineEntry::Make(this, getCurrentSection().first);
270
271  this->MCStreamer::EmitDwarfLocDirective(FileNo, Line, Column, Flags,
272                                          Isa, Discriminator, FileName);
273}
274
275void MCObjectStreamer::EmitDwarfAdvanceLineAddr(int64_t LineDelta,
276                                                const MCSymbol *LastLabel,
277                                                const MCSymbol *Label,
278                                                unsigned PointerSize) {
279  if (!LastLabel) {
280    EmitDwarfSetLineAddr(LineDelta, Label, PointerSize);
281    return;
282  }
283  const MCExpr *AddrDelta = BuildSymbolDiff(getContext(), Label, LastLabel);
284  int64_t Res;
285  if (AddrDelta->EvaluateAsAbsolute(Res, getAssembler())) {
286    MCDwarfLineAddr::Emit(this, LineDelta, Res);
287    return;
288  }
289  AddrDelta = ForceExpAbs(AddrDelta);
290  insert(new MCDwarfLineAddrFragment(LineDelta, *AddrDelta));
291}
292
293void MCObjectStreamer::EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel,
294                                                 const MCSymbol *Label) {
295  const MCExpr *AddrDelta = BuildSymbolDiff(getContext(), Label, LastLabel);
296  int64_t Res;
297  if (AddrDelta->EvaluateAsAbsolute(Res, getAssembler())) {
298    MCDwarfFrameEmitter::EmitAdvanceLoc(*this, Res);
299    return;
300  }
301  AddrDelta = ForceExpAbs(AddrDelta);
302  insert(new MCDwarfCallFrameFragment(*AddrDelta));
303}
304
305void MCObjectStreamer::EmitBytes(StringRef Data, unsigned AddrSpace) {
306  assert(AddrSpace == 0 && "Address space must be 0!");
307  getOrCreateDataFragment()->getContents().append(Data.begin(), Data.end());
308}
309
310void MCObjectStreamer::EmitValueToAlignment(unsigned ByteAlignment,
311                                            int64_t Value,
312                                            unsigned ValueSize,
313                                            unsigned MaxBytesToEmit) {
314  if (MaxBytesToEmit == 0)
315    MaxBytesToEmit = ByteAlignment;
316  insert(new MCAlignFragment(ByteAlignment, Value, ValueSize, MaxBytesToEmit));
317
318  // Update the maximum alignment on the current section if necessary.
319  if (ByteAlignment > getCurrentSectionData()->getAlignment())
320    getCurrentSectionData()->setAlignment(ByteAlignment);
321}
322
323void MCObjectStreamer::EmitCodeAlignment(unsigned ByteAlignment,
324                                         unsigned MaxBytesToEmit) {
325  EmitValueToAlignment(ByteAlignment, 0, 1, MaxBytesToEmit);
326  cast<MCAlignFragment>(getCurrentFragment())->setEmitNops(true);
327}
328
329bool MCObjectStreamer::EmitValueToOffset(const MCExpr *Offset,
330                                         unsigned char Value) {
331  int64_t Res;
332  if (Offset->EvaluateAsAbsolute(Res, getAssembler())) {
333    insert(new MCOrgFragment(*Offset, Value));
334    return false;
335  }
336
337  MCSymbol *CurrentPos = getContext().CreateTempSymbol();
338  EmitLabel(CurrentPos);
339  MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
340  const MCExpr *Ref =
341    MCSymbolRefExpr::Create(CurrentPos, Variant, getContext());
342  const MCExpr *Delta =
343    MCBinaryExpr::Create(MCBinaryExpr::Sub, Offset, Ref, getContext());
344
345  if (!Delta->EvaluateAsAbsolute(Res, getAssembler()))
346    return true;
347  EmitFill(Res, Value);
348  return false;
349}
350
351// Associate GPRel32 fixup with data and resize data area
352void MCObjectStreamer::EmitGPRel32Value(const MCExpr *Value) {
353  MCDataFragment *DF = getOrCreateDataFragment();
354
355  DF->getFixups().push_back(MCFixup::Create(DF->getContents().size(),
356                                            Value, FK_GPRel_4));
357  DF->getContents().resize(DF->getContents().size() + 4, 0);
358}
359
360// Associate GPRel32 fixup with data and resize data area
361void MCObjectStreamer::EmitGPRel64Value(const MCExpr *Value) {
362  MCDataFragment *DF = getOrCreateDataFragment();
363
364  DF->getFixups().push_back(MCFixup::Create(DF->getContents().size(),
365                                            Value, FK_GPRel_4));
366  DF->getContents().resize(DF->getContents().size() + 8, 0);
367}
368
369void MCObjectStreamer::EmitFill(uint64_t NumBytes, uint8_t FillValue,
370                                unsigned AddrSpace) {
371  assert(AddrSpace == 0 && "Address space must be 0!");
372  // FIXME: A MCFillFragment would be more memory efficient but MCExpr has
373  //        problems evaluating expressions across multiple fragments.
374  getOrCreateDataFragment()->getContents().append(NumBytes, FillValue);
375}
376
377void MCObjectStreamer::FinishImpl() {
378  // Dump out the dwarf file & directory tables and line tables.
379  const MCSymbol *LineSectionSymbol = NULL;
380  if (getContext().hasDwarfFiles())
381    LineSectionSymbol = MCDwarfFileTable::Emit(this);
382
383  // If we are generating dwarf for assembly source files dump out the sections.
384  if (getContext().getGenDwarfForAssembly())
385    MCGenDwarfInfo::Emit(this, LineSectionSymbol);
386
387  getAssembler().Finish();
388}
389