PageRenderTime 39ms CodeModel.GetById 14ms app.highlight 20ms RepoModel.GetById 0ms app.codeStats 0ms

/3rd_party/llvm/lib/MC/MCObjectStreamer.cpp

https://code.google.com/p/softart/
C++ | 393 lines | 294 code | 63 blank | 36 comment | 32 complexity | 43f3adff5ece50116e446307bd92824d MD5 | raw file
Possible License(s): LGPL-2.1, BSD-3-Clause, JSON, MPL-2.0-no-copyleft-exception, GPL-2.0, GPL-3.0, LGPL-3.0, BSD-2-Clause
  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/MC/MCSection.h"
 22#include "llvm/Support/ErrorHandling.h"
 23using namespace llvm;
 24
 25MCObjectStreamer::MCObjectStreamer(MCContext &Context,
 26                                   MCTargetStreamer *TargetStreamer,
 27                                   MCAsmBackend &TAB, raw_ostream &OS,
 28                                   MCCodeEmitter *Emitter_)
 29    : MCStreamer(Context, TargetStreamer),
 30      Assembler(new MCAssembler(Context, TAB, *Emitter_,
 31                                *TAB.createObjectWriter(OS), OS)),
 32      CurSectionData(0) {}
 33
 34MCObjectStreamer::MCObjectStreamer(MCContext &Context,
 35                                   MCTargetStreamer *TargetStreamer,
 36                                   MCAsmBackend &TAB, raw_ostream &OS,
 37                                   MCCodeEmitter *Emitter_,
 38                                   MCAssembler *_Assembler)
 39    : MCStreamer(Context, TargetStreamer), Assembler(_Assembler),
 40      CurSectionData(0) {}
 41
 42MCObjectStreamer::~MCObjectStreamer() {
 43  delete &Assembler->getBackend();
 44  delete &Assembler->getEmitter();
 45  delete &Assembler->getWriter();
 46  delete Assembler;
 47}
 48
 49void MCObjectStreamer::reset() {
 50  if (Assembler)
 51    Assembler->reset();
 52  CurSectionData = 0;
 53  CurInsertionPoint = MCSectionData::iterator();
 54  MCStreamer::reset();
 55}
 56
 57MCFragment *MCObjectStreamer::getCurrentFragment() const {
 58  assert(getCurrentSectionData() && "No current section!");
 59
 60  if (CurInsertionPoint != getCurrentSectionData()->getFragmentList().begin())
 61    return prior(CurInsertionPoint);
 62
 63  return 0;
 64}
 65
 66MCDataFragment *MCObjectStreamer::getOrCreateDataFragment() const {
 67  MCDataFragment *F = dyn_cast_or_null<MCDataFragment>(getCurrentFragment());
 68  // When bundling is enabled, we don't want to add data to a fragment that
 69  // already has instructions (see MCELFStreamer::EmitInstToData for details)
 70  if (!F || (Assembler->isBundlingEnabled() && F->hasInstructions())) {
 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  Symbol->setVariableValue(AddValueSymbols(Value));
193}
194
195void MCObjectStreamer::EmitInstruction(const MCInst &Inst) {
196  // Scan for values.
197  for (unsigned i = Inst.getNumOperands(); i--; )
198    if (Inst.getOperand(i).isExpr())
199      AddValueSymbols(Inst.getOperand(i).getExpr());
200
201  MCSectionData *SD = getCurrentSectionData();
202  SD->setHasInstructions(true);
203
204  // Now that a machine instruction has been assembled into this section, make
205  // a line entry for any .loc directive that has been seen.
206  MCLineEntry::Make(this, getCurrentSection().first);
207
208  // If this instruction doesn't need relaxation, just emit it as data.
209  MCAssembler &Assembler = getAssembler();
210  if (!Assembler.getBackend().mayNeedRelaxation(Inst)) {
211    EmitInstToData(Inst);
212    return;
213  }
214
215  // Otherwise, relax and emit it as data if either:
216  // - The RelaxAll flag was passed
217  // - Bundling is enabled and this instruction is inside a bundle-locked
218  //   group. We want to emit all such instructions into the same data
219  //   fragment.
220  if (Assembler.getRelaxAll() ||
221      (Assembler.isBundlingEnabled() && SD->isBundleLocked())) {
222    MCInst Relaxed;
223    getAssembler().getBackend().relaxInstruction(Inst, Relaxed);
224    while (getAssembler().getBackend().mayNeedRelaxation(Relaxed))
225      getAssembler().getBackend().relaxInstruction(Relaxed, Relaxed);
226    EmitInstToData(Relaxed);
227    return;
228  }
229
230  // Otherwise emit to a separate fragment.
231  EmitInstToFragment(Inst);
232}
233
234void MCObjectStreamer::EmitInstToFragment(const MCInst &Inst) {
235  // Always create a new, separate fragment here, because its size can change
236  // during relaxation.
237  MCRelaxableFragment *IF = new MCRelaxableFragment(Inst);
238  insert(IF);
239
240  SmallString<128> Code;
241  raw_svector_ostream VecOS(Code);
242  getAssembler().getEmitter().EncodeInstruction(Inst, VecOS, IF->getFixups());
243  VecOS.flush();
244  IF->getContents().append(Code.begin(), Code.end());
245}
246
247#ifndef NDEBUG
248static const char *const BundlingNotImplementedMsg =
249  "Aligned bundling is not implemented for this object format";
250#endif
251
252void MCObjectStreamer::EmitBundleAlignMode(unsigned AlignPow2) {
253  llvm_unreachable(BundlingNotImplementedMsg);
254}
255
256void MCObjectStreamer::EmitBundleLock(bool AlignToEnd) {
257  llvm_unreachable(BundlingNotImplementedMsg);
258}
259
260void MCObjectStreamer::EmitBundleUnlock() {
261  llvm_unreachable(BundlingNotImplementedMsg);
262}
263
264void MCObjectStreamer::EmitDwarfLocDirective(unsigned FileNo, unsigned Line,
265                                             unsigned Column, unsigned Flags,
266                                             unsigned Isa,
267                                             unsigned Discriminator,
268                                             StringRef FileName) {
269  // In case we see two .loc directives in a row, make sure the
270  // first one gets a line entry.
271  MCLineEntry::Make(this, getCurrentSection().first);
272
273  this->MCStreamer::EmitDwarfLocDirective(FileNo, Line, Column, Flags,
274                                          Isa, Discriminator, FileName);
275}
276
277void MCObjectStreamer::EmitDwarfAdvanceLineAddr(int64_t LineDelta,
278                                                const MCSymbol *LastLabel,
279                                                const MCSymbol *Label,
280                                                unsigned PointerSize) {
281  if (!LastLabel) {
282    EmitDwarfSetLineAddr(LineDelta, Label, PointerSize);
283    return;
284  }
285  const MCExpr *AddrDelta = BuildSymbolDiff(getContext(), Label, LastLabel);
286  int64_t Res;
287  if (AddrDelta->EvaluateAsAbsolute(Res, getAssembler())) {
288    MCDwarfLineAddr::Emit(this, LineDelta, Res);
289    return;
290  }
291  AddrDelta = ForceExpAbs(AddrDelta);
292  insert(new MCDwarfLineAddrFragment(LineDelta, *AddrDelta));
293}
294
295void MCObjectStreamer::EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel,
296                                                 const MCSymbol *Label) {
297  const MCExpr *AddrDelta = BuildSymbolDiff(getContext(), Label, LastLabel);
298  int64_t Res;
299  if (AddrDelta->EvaluateAsAbsolute(Res, getAssembler())) {
300    MCDwarfFrameEmitter::EmitAdvanceLoc(*this, Res);
301    return;
302  }
303  AddrDelta = ForceExpAbs(AddrDelta);
304  insert(new MCDwarfCallFrameFragment(*AddrDelta));
305}
306
307void MCObjectStreamer::EmitBytes(StringRef Data) {
308  MCLineEntry::Make(this, getCurrentSection().first);
309  getOrCreateDataFragment()->getContents().append(Data.begin(), Data.end());
310}
311
312void MCObjectStreamer::EmitValueToAlignment(unsigned ByteAlignment,
313                                            int64_t Value,
314                                            unsigned ValueSize,
315                                            unsigned MaxBytesToEmit) {
316  if (MaxBytesToEmit == 0)
317    MaxBytesToEmit = ByteAlignment;
318  insert(new MCAlignFragment(ByteAlignment, Value, ValueSize, MaxBytesToEmit));
319
320  // Update the maximum alignment on the current section if necessary.
321  if (ByteAlignment > getCurrentSectionData()->getAlignment())
322    getCurrentSectionData()->setAlignment(ByteAlignment);
323}
324
325void MCObjectStreamer::EmitCodeAlignment(unsigned ByteAlignment,
326                                         unsigned MaxBytesToEmit) {
327  EmitValueToAlignment(ByteAlignment, 0, 1, MaxBytesToEmit);
328  cast<MCAlignFragment>(getCurrentFragment())->setEmitNops(true);
329}
330
331bool MCObjectStreamer::EmitValueToOffset(const MCExpr *Offset,
332                                         unsigned char Value) {
333  int64_t Res;
334  if (Offset->EvaluateAsAbsolute(Res, getAssembler())) {
335    insert(new MCOrgFragment(*Offset, Value));
336    return false;
337  }
338
339  MCSymbol *CurrentPos = getContext().CreateTempSymbol();
340  EmitLabel(CurrentPos);
341  MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
342  const MCExpr *Ref =
343    MCSymbolRefExpr::Create(CurrentPos, Variant, getContext());
344  const MCExpr *Delta =
345    MCBinaryExpr::Create(MCBinaryExpr::Sub, Offset, Ref, getContext());
346
347  if (!Delta->EvaluateAsAbsolute(Res, getAssembler()))
348    return true;
349  EmitFill(Res, Value);
350  return false;
351}
352
353// Associate GPRel32 fixup with data and resize data area
354void MCObjectStreamer::EmitGPRel32Value(const MCExpr *Value) {
355  MCDataFragment *DF = getOrCreateDataFragment();
356
357  DF->getFixups().push_back(MCFixup::Create(DF->getContents().size(), 
358                                            Value, FK_GPRel_4));
359  DF->getContents().resize(DF->getContents().size() + 4, 0);
360}
361
362// Associate GPRel32 fixup with data and resize data area
363void MCObjectStreamer::EmitGPRel64Value(const MCExpr *Value) {
364  MCDataFragment *DF = getOrCreateDataFragment();
365
366  DF->getFixups().push_back(MCFixup::Create(DF->getContents().size(), 
367                                            Value, FK_GPRel_4));
368  DF->getContents().resize(DF->getContents().size() + 8, 0);
369}
370
371void MCObjectStreamer::EmitFill(uint64_t NumBytes, uint8_t FillValue) {
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::EmitZeros(uint64_t NumBytes) {
378  unsigned ItemSize = getCurrentSection().first->isVirtualSection() ? 0 : 1;
379  insert(new MCFillFragment(0, ItemSize, NumBytes));
380}
381
382void MCObjectStreamer::FinishImpl() {
383  // Dump out the dwarf file & directory tables and line tables.
384  const MCSymbol *LineSectionSymbol = NULL;
385  if (getContext().hasDwarfFiles())
386    LineSectionSymbol = MCDwarfFileTable::Emit(this);
387
388  // If we are generating dwarf for assembly source files dump out the sections.
389  if (getContext().getGenDwarfForAssembly())
390    MCGenDwarfInfo::Emit(this, LineSectionSymbol);
391
392  getAssembler().Finish();
393}