/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

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