MCObjectStreamer.cpp revision 6c1d4972cf1cd6b6072e31c05f97abb1ed7a8497
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  MCInstFragment *IF = new MCInstFragment(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
229const char *BundlingNotImplementedMsg =
230  "Aligned bundling is not implemented for this object format";
231
232void MCObjectStreamer::EmitBundleAlignMode(unsigned AlignPow2) {
233  llvm_unreachable(BundlingNotImplementedMsg);
234}
235
236void MCObjectStreamer::EmitBundleLock(bool AlignToEnd) {
237  llvm_unreachable(BundlingNotImplementedMsg);
238}
239
240void MCObjectStreamer::EmitBundleUnlock() {
241  llvm_unreachable(BundlingNotImplementedMsg);
242}
243
244void MCObjectStreamer::EmitDwarfAdvanceLineAddr(int64_t LineDelta,
245                                                const MCSymbol *LastLabel,
246                                                const MCSymbol *Label,
247                                                unsigned PointerSize) {
248  if (!LastLabel) {
249    EmitDwarfSetLineAddr(LineDelta, Label, PointerSize);
250    return;
251  }
252  const MCExpr *AddrDelta = BuildSymbolDiff(getContext(), Label, LastLabel);
253  int64_t Res;
254  if (AddrDelta->EvaluateAsAbsolute(Res, getAssembler())) {
255    MCDwarfLineAddr::Emit(this, LineDelta, Res);
256    return;
257  }
258  AddrDelta = ForceExpAbs(AddrDelta);
259  new MCDwarfLineAddrFragment(LineDelta, *AddrDelta, getCurrentSectionData());
260}
261
262void MCObjectStreamer::EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel,
263                                                 const MCSymbol *Label) {
264  const MCExpr *AddrDelta = BuildSymbolDiff(getContext(), Label, LastLabel);
265  int64_t Res;
266  if (AddrDelta->EvaluateAsAbsolute(Res, getAssembler())) {
267    MCDwarfFrameEmitter::EmitAdvanceLoc(*this, Res);
268    return;
269  }
270  AddrDelta = ForceExpAbs(AddrDelta);
271  new MCDwarfCallFrameFragment(*AddrDelta, getCurrentSectionData());
272}
273
274void MCObjectStreamer::EmitBytes(StringRef Data, unsigned AddrSpace) {
275  assert(AddrSpace == 0 && "Address space must be 0!");
276  getOrCreateDataFragment()->getContents().append(Data.begin(), Data.end());
277}
278
279void MCObjectStreamer::EmitValueToAlignment(unsigned ByteAlignment,
280                                            int64_t Value,
281                                            unsigned ValueSize,
282                                            unsigned MaxBytesToEmit) {
283  if (MaxBytesToEmit == 0)
284    MaxBytesToEmit = ByteAlignment;
285  new MCAlignFragment(ByteAlignment, Value, ValueSize, MaxBytesToEmit,
286                      getCurrentSectionData());
287
288  // Update the maximum alignment on the current section if necessary.
289  if (ByteAlignment > getCurrentSectionData()->getAlignment())
290    getCurrentSectionData()->setAlignment(ByteAlignment);
291}
292
293void MCObjectStreamer::EmitCodeAlignment(unsigned ByteAlignment,
294                                         unsigned MaxBytesToEmit) {
295  EmitValueToAlignment(ByteAlignment, 0, 1, MaxBytesToEmit);
296  cast<MCAlignFragment>(getCurrentFragment())->setEmitNops(true);
297}
298
299bool MCObjectStreamer::EmitValueToOffset(const MCExpr *Offset,
300                                         unsigned char Value) {
301  int64_t Res;
302  if (Offset->EvaluateAsAbsolute(Res, getAssembler())) {
303    new MCOrgFragment(*Offset, Value, getCurrentSectionData());
304    return false;
305  }
306
307  MCSymbol *CurrentPos = getContext().CreateTempSymbol();
308  EmitLabel(CurrentPos);
309  MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
310  const MCExpr *Ref =
311    MCSymbolRefExpr::Create(CurrentPos, Variant, getContext());
312  const MCExpr *Delta =
313    MCBinaryExpr::Create(MCBinaryExpr::Sub, Offset, Ref, getContext());
314
315  if (!Delta->EvaluateAsAbsolute(Res, getAssembler()))
316    return true;
317  EmitFill(Res, Value, 0);
318  return false;
319}
320
321// Associate GPRel32 fixup with data and resize data area
322void MCObjectStreamer::EmitGPRel32Value(const MCExpr *Value) {
323  MCDataFragment *DF = getOrCreateDataFragment();
324
325  DF->getFixups().push_back(MCFixup::Create(DF->getContents().size(),
326                                            Value, FK_GPRel_4));
327  DF->getContents().resize(DF->getContents().size() + 4, 0);
328}
329
330// Associate GPRel32 fixup with data and resize data area
331void MCObjectStreamer::EmitGPRel64Value(const MCExpr *Value) {
332  MCDataFragment *DF = getOrCreateDataFragment();
333
334  DF->getFixups().push_back(MCFixup::Create(DF->getContents().size(),
335                                            Value, FK_GPRel_4));
336  DF->getContents().resize(DF->getContents().size() + 8, 0);
337}
338
339void MCObjectStreamer::EmitFill(uint64_t NumBytes, uint8_t FillValue,
340                                unsigned AddrSpace) {
341  assert(AddrSpace == 0 && "Address space must be 0!");
342  // FIXME: A MCFillFragment would be more memory efficient but MCExpr has
343  //        problems evaluating expressions across multiple fragments.
344  getOrCreateDataFragment()->getContents().append(NumBytes, FillValue);
345}
346
347void MCObjectStreamer::FinishImpl() {
348  // Dump out the dwarf file & directory tables and line tables.
349  const MCSymbol *LineSectionSymbol = NULL;
350  if (getContext().hasDwarfFiles())
351    LineSectionSymbol = MCDwarfFileTable::Emit(this);
352
353  // If we are generating dwarf for assembly source files dump out the sections.
354  if (getContext().getGenDwarfForAssembly())
355    MCGenDwarfInfo::Emit(this, LineSectionSymbol);
356
357  getAssembler().Finish();
358}
359