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