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