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