blob: 3ed9a6fbf6b36599b4456ad841c298c36a0e5711 [file] [log] [blame]
Daniel Dunbar8a3c9d92010-06-16 20:04:22 +00001//===- 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"
Peter Collingbourne2f495b92013-04-17 21:18:16 +000011#include "llvm/ADT/STLExtras.h"
Craig Topper6e80c282012-03-26 06:58:25 +000012#include "llvm/MC/MCAsmBackend.h"
Daniel Dunbar8a3c9d92010-06-16 20:04:22 +000013#include "llvm/MC/MCAssembler.h"
Benjamin Kramera3e0ddb2010-07-29 17:48:06 +000014#include "llvm/MC/MCCodeEmitter.h"
Reid Klecknera5b1eef2016-08-26 17:58:37 +000015#include "llvm/MC/MCCodeView.h"
Rafael Espindola0a017a62010-12-10 07:39:47 +000016#include "llvm/MC/MCContext.h"
Rafael Espindola72b54882010-11-01 16:27:31 +000017#include "llvm/MC/MCDwarf.h"
Michael J. Spencere2da0a42010-07-19 06:13:10 +000018#include "llvm/MC/MCExpr.h"
Craig Topper6e80c282012-03-26 06:58:25 +000019#include "llvm/MC/MCObjectWriter.h"
Serge Pavlov24a3ebb2013-06-27 14:35:03 +000020#include "llvm/MC/MCSection.h"
Chandler Carruth8a8cd2b2014-01-07 11:48:04 +000021#include "llvm/MC/MCSymbol.h"
Craig Topper6e80c282012-03-26 06:58:25 +000022#include "llvm/Support/ErrorHandling.h"
Petr Hosek67a94a72016-05-28 05:57:48 +000023#include "llvm/Support/SourceMgr.h"
Daniel Dunbar8a3c9d92010-06-16 20:04:22 +000024using namespace llvm;
25
Lang Hames02d33052017-10-11 01:57:21 +000026MCObjectStreamer::MCObjectStreamer(MCContext &Context,
27 std::unique_ptr<MCAsmBackend> TAB,
Peter Collingbournef7b81db2018-05-18 18:26:45 +000028 std::unique_ptr<MCObjectWriter> OW,
Lang Hames2241ffa2017-10-11 23:34:47 +000029 std::unique_ptr<MCCodeEmitter> Emitter)
Nirav Dave8728e092018-04-27 15:45:27 +000030 : MCStreamer(Context),
Peter Collingbournef7b81db2018-05-18 18:26:45 +000031 Assembler(llvm::make_unique<MCAssembler>(
32 Context, std::move(TAB), std::move(Emitter), std::move(OW))),
Rafael Espindola2f9bdd82015-05-27 20:52:32 +000033 EmitEHFrame(true), EmitDebugFrame(false) {}
Daniel Dunbar8a3c9d92010-06-16 20:04:22 +000034
Lang Hames2241ffa2017-10-11 23:34:47 +000035MCObjectStreamer::~MCObjectStreamer() {}
Daniel Dunbarb2347fe2010-06-16 20:04:25 +000036
Nirav Dave6c0665e2018-04-30 19:22:40 +000037// AssemblerPtr is used for evaluation of expressions and causes
38// difference between asm and object outputs. Return nullptr to in
39// inline asm mode to limit divergence to assembly inputs.
40MCAssembler *MCObjectStreamer::getAssemblerPtr() {
41 if (getUseAssemblerInfoForParsing())
42 return Assembler.get();
43 return nullptr;
44}
45
Petr Hosek9e0c8902015-04-12 23:42:25 +000046void MCObjectStreamer::flushPendingLabels(MCFragment *F, uint64_t FOffset) {
Rafael Espindola81413c02015-10-03 00:57:12 +000047 if (PendingLabels.empty())
48 return;
49 if (!F) {
50 F = new MCDataFragment();
51 MCSection *CurSection = getCurrentSectionOnly();
52 CurSection->getFragmentList().insert(CurInsertionPoint, F);
53 F->setParent(CurSection);
Derek Schuff5f708e52014-10-22 22:38:06 +000054 }
Rafael Espindola81413c02015-10-03 00:57:12 +000055 for (MCSymbol *Sym : PendingLabels) {
56 Sym->setFragment(F);
57 Sym->setOffset(FOffset);
58 }
59 PendingLabels.clear();
Derek Schuff5f708e52014-10-22 22:38:06 +000060}
61
Sam Clegg87cc4db2018-05-02 23:01:10 +000062void MCObjectStreamer::addFragmentAtoms() {
63 // First, scan the symbol table to build a lookup table from fragments to
64 // defining symbols.
65 DenseMap<const MCFragment *, const MCSymbol *> DefiningSymbolMap;
66 for (const MCSymbol &Symbol : getAssembler().symbols()) {
67 if (getAssembler().isSymbolLinkerVisible(Symbol) && Symbol.isInSection() &&
68 !Symbol.isVariable()) {
69 // An atom defining symbol should never be internal to a fragment.
70 assert(Symbol.getOffset() == 0 &&
71 "Invalid offset in atom defining symbol!");
72 DefiningSymbolMap[Symbol.getFragment()] = &Symbol;
73 }
74 }
75
76 // Set the fragment atom associations by tracking the last seen atom defining
77 // symbol.
78 for (MCSection &Sec : getAssembler()) {
79 const MCSymbol *CurrentAtom = nullptr;
80 for (MCFragment &Frag : Sec) {
81 if (const MCSymbol *Symbol = DefiningSymbolMap.lookup(&Frag))
82 CurrentAtom = Symbol;
83 Frag.setAtom(CurrentAtom);
84 }
85 }
86}
87
Rafael Espindolad09b4162018-02-09 17:00:25 +000088// As a compile-time optimization, avoid allocating and evaluating an MCExpr
89// tree for (Hi - Lo) when Hi and Lo are offsets into the same fragment.
90static Optional<uint64_t> absoluteSymbolDiff(const MCSymbol *Hi,
91 const MCSymbol *Lo) {
Reid Kleckner5a791ee2018-03-15 21:24:04 +000092 assert(Hi && Lo);
Rafael Espindolad09b4162018-02-09 17:00:25 +000093 if (!Hi->getFragment() || Hi->getFragment() != Lo->getFragment() ||
94 Hi->isVariable() || Lo->isVariable())
95 return None;
96
97 return Hi->getOffset() - Lo->getOffset();
98}
99
Rafael Espindola7c6e6e42015-06-11 18:58:08 +0000100void MCObjectStreamer::emitAbsoluteSymbolDiff(const MCSymbol *Hi,
Duncan P. N. Exon Smith0b73d712015-05-21 02:41:23 +0000101 const MCSymbol *Lo,
102 unsigned Size) {
Rafael Espindolad09b4162018-02-09 17:00:25 +0000103 if (Optional<uint64_t> Diff = absoluteSymbolDiff(Hi, Lo)) {
104 EmitIntValue(*Diff, Size);
Rafael Espindola7c6e6e42015-06-11 18:58:08 +0000105 return;
106 }
Rafael Espindolad09b4162018-02-09 17:00:25 +0000107 MCStreamer::emitAbsoluteSymbolDiff(Hi, Lo, Size);
108}
Duncan P. N. Exon Smith0b73d712015-05-21 02:41:23 +0000109
Rafael Espindolad09b4162018-02-09 17:00:25 +0000110void MCObjectStreamer::emitAbsoluteSymbolDiffAsULEB128(const MCSymbol *Hi,
111 const MCSymbol *Lo) {
112 if (Optional<uint64_t> Diff = absoluteSymbolDiff(Hi, Lo)) {
113 EmitULEB128IntValue(*Diff);
114 return;
115 }
116 MCStreamer::emitAbsoluteSymbolDiffAsULEB128(Hi, Lo);
Duncan P. N. Exon Smith0b73d712015-05-21 02:41:23 +0000117}
118
Pedro Artigas7212ee42012-12-12 22:59:46 +0000119void MCObjectStreamer::reset() {
Pedro Artigasb95c53e2012-12-14 18:52:11 +0000120 if (Assembler)
121 Assembler->reset();
Rafael Espindolaa32d0e92015-05-27 15:14:11 +0000122 CurInsertionPoint = MCSection::iterator();
Rafael Espindola3dd8ef62014-05-12 14:02:44 +0000123 EmitEHFrame = true;
124 EmitDebugFrame = false;
Derek Schuff5f708e52014-10-22 22:38:06 +0000125 PendingLabels.clear();
Pedro Artigas7212ee42012-12-12 22:59:46 +0000126 MCStreamer::reset();
127}
128
Rafael Espindola3dd8ef62014-05-12 14:02:44 +0000129void MCObjectStreamer::EmitFrames(MCAsmBackend *MAB) {
130 if (!getNumFrameInfos())
131 return;
132
133 if (EmitEHFrame)
134 MCDwarfFrameEmitter::Emit(*this, MAB, true);
135
136 if (EmitDebugFrame)
137 MCDwarfFrameEmitter::Emit(*this, MAB, false);
138}
139
Michael J. Spencere2da0a42010-07-19 06:13:10 +0000140MCFragment *MCObjectStreamer::getCurrentFragment() const {
Rafael Espindola983bec62015-05-27 21:04:14 +0000141 assert(getCurrentSectionOnly() && "No current section!");
Michael J. Spencere2da0a42010-07-19 06:13:10 +0000142
Rafael Espindola983bec62015-05-27 21:04:14 +0000143 if (CurInsertionPoint != getCurrentSectionOnly()->getFragmentList().begin())
Duncan P. N. Exon Smitha5f45da2015-10-10 00:13:11 +0000144 return &*std::prev(CurInsertionPoint);
Michael J. Spencere2da0a42010-07-19 06:13:10 +0000145
Craig Topperbb694de2014-04-13 04:57:38 +0000146 return nullptr;
Michael J. Spencere2da0a42010-07-19 06:13:10 +0000147}
148
Derek Schuff5f708e52014-10-22 22:38:06 +0000149MCDataFragment *MCObjectStreamer::getOrCreateDataFragment() {
Michael J. Spencere2da0a42010-07-19 06:13:10 +0000150 MCDataFragment *F = dyn_cast_or_null<MCDataFragment>(getCurrentFragment());
Derek Schuff8878bcc92013-02-15 22:50:52 +0000151 // When bundling is enabled, we don't want to add data to a fragment that
152 // already has instructions (see MCELFStreamer::EmitInstToData for details)
Petr Hosek9e0c8902015-04-12 23:42:25 +0000153 if (!F || (Assembler->isBundlingEnabled() && !Assembler->getRelaxAll() &&
154 F->hasInstructions())) {
David Blaikie4d3b0432014-04-10 21:53:47 +0000155 F = new MCDataFragment();
Peter Collingbourne2f495b92013-04-17 21:18:16 +0000156 insert(F);
157 }
Michael J. Spencere2da0a42010-07-19 06:13:10 +0000158 return F;
159}
160
Omer Paparo Bivas2251c792017-10-24 06:16:03 +0000161MCPaddingFragment *MCObjectStreamer::getOrCreatePaddingFragment() {
162 MCPaddingFragment *F =
163 dyn_cast_or_null<MCPaddingFragment>(getCurrentFragment());
164 if (!F) {
165 F = new MCPaddingFragment();
166 insert(F);
167 }
168 return F;
169}
170
Rafael Espindola2be12812014-06-25 15:29:54 +0000171void MCObjectStreamer::visitUsedSymbol(const MCSymbol &Sym) {
Rafael Espindolab5d316b2015-05-29 20:21:02 +0000172 Assembler->registerSymbol(Sym);
Rafael Espindola2be12812014-06-25 15:29:54 +0000173}
174
Rafael Espindola3dd8ef62014-05-12 14:02:44 +0000175void MCObjectStreamer::EmitCFISections(bool EH, bool Debug) {
176 MCStreamer::EmitCFISections(EH, Debug);
177 EmitEHFrame = EH;
178 EmitDebugFrame = Debug;
179}
180
Kevin Enderby96918bc2014-04-22 17:27:29 +0000181void MCObjectStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size,
Craig Topper3c76c522015-09-20 23:35:59 +0000182 SMLoc Loc) {
Rafael Espindola591c6412014-06-25 18:37:33 +0000183 MCStreamer::EmitValueImpl(Value, Size, Loc);
Rafael Espindolaa084fd62010-11-28 23:08:47 +0000184 MCDataFragment *DF = getOrCreateDataFragment();
Petr Hosek32946702015-06-27 01:54:17 +0000185 flushPendingLabels(DF, DF->getContents().size());
Rafael Espindolaa084fd62010-11-28 23:08:47 +0000186
Reid Kleckner2214ed82016-01-29 00:49:42 +0000187 MCCVLineEntry::Make(this);
Eric Christopher445c9522016-10-14 05:47:37 +0000188 MCDwarfLineEntry::Make(this, getCurrentSectionOnly());
Cameron Zwarich80cbcd22013-05-25 21:56:53 +0000189
Rafael Espindolaa084fd62010-11-28 23:08:47 +0000190 // Avoid fixups when possible.
191 int64_t AbsValue;
Nirav Dave6c0665e2018-04-30 19:22:40 +0000192 if (Value->evaluateAsAbsolute(AbsValue, getAssemblerPtr())) {
Arnaud A. de Grandmaison6d241792017-05-15 08:43:27 +0000193 if (!isUIntN(8 * Size, AbsValue) && !isIntN(8 * Size, AbsValue)) {
194 getContext().reportError(
195 Loc, "value evaluated as " + Twine(AbsValue) + " is out of range.");
196 return;
197 }
Rafael Espindola64e1af82013-07-02 15:49:13 +0000198 EmitIntValue(AbsValue, Size);
Rafael Espindola4c70eea2010-12-03 02:54:21 +0000199 return;
Rafael Espindolaa084fd62010-11-28 23:08:47 +0000200 }
Eli Benderskya31a8942012-12-07 19:13:57 +0000201 DF->getFixups().push_back(
Jim Grosbach63661f82015-05-15 19:13:05 +0000202 MCFixup::create(DF->getContents().size(), Value,
Kevin Enderby96918bc2014-04-22 17:27:29 +0000203 MCFixup::getKindForSize(Size, false), Loc));
Rafael Espindola4c70eea2010-12-03 02:54:21 +0000204 DF->getContents().resize(DF->getContents().size() + Size, 0);
Rafael Espindolaa084fd62010-11-28 23:08:47 +0000205}
206
Reid Klecknerab23dac2017-10-10 00:57:36 +0000207MCSymbol *MCObjectStreamer::EmitCFILabel() {
208 MCSymbol *Label = getContext().createTempSymbol("cfi", true);
209 EmitLabel(Label);
210 return Label;
211}
212
Oliver Stannardcf6bfb12014-11-03 12:19:03 +0000213void MCObjectStreamer::EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) {
214 // We need to create a local symbol to avoid relocations.
Jim Grosbach6f482002015-05-18 18:43:14 +0000215 Frame.Begin = getContext().createTempSymbol();
Oliver Stannardcf6bfb12014-11-03 12:19:03 +0000216 EmitLabel(Frame.Begin);
Rafael Espindola38241202012-01-07 22:42:19 +0000217}
218
Rafael Espindolaf28213c2012-01-09 00:17:29 +0000219void MCObjectStreamer::EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) {
Jim Grosbach6f482002015-05-18 18:43:14 +0000220 Frame.End = getContext().createTempSymbol();
Rafael Espindola49bbfd02014-06-25 00:13:59 +0000221 EmitLabel(Frame.End);
Rafael Espindolaf28213c2012-01-09 00:17:29 +0000222}
223
Rafael Espindolabe991572017-02-10 15:13:12 +0000224void MCObjectStreamer::EmitLabel(MCSymbol *Symbol, SMLoc Loc) {
225 MCStreamer::EmitLabel(Symbol, Loc);
Rafael Espindolae5b74152010-11-28 17:18:55 +0000226
Rafael Espindolab5d316b2015-05-29 20:21:02 +0000227 getAssembler().registerSymbol(*Symbol);
Derek Schuff5f708e52014-10-22 22:38:06 +0000228
229 // If there is a current fragment, mark the symbol as pointing into it.
230 // Otherwise queue the label and set its fragment pointer when we emit the
231 // next fragment.
Petr Hosek9e0c8902015-04-12 23:42:25 +0000232 auto *F = dyn_cast_or_null<MCDataFragment>(getCurrentFragment());
233 if (F && !(getAssembler().isBundlingEnabled() &&
234 getAssembler().getRelaxAll())) {
Rafael Espindola4d37b2a2015-05-29 21:45:01 +0000235 Symbol->setFragment(F);
Rafael Espindola14672502015-05-29 17:48:04 +0000236 Symbol->setOffset(F->getContents().size());
Derek Schuff5f708e52014-10-22 22:38:06 +0000237 } else {
Rafael Espindola66ccf492015-05-29 17:41:59 +0000238 PendingLabels.push_back(Symbol);
Derek Schuff5f708e52014-10-22 22:38:06 +0000239 }
Rafael Espindolae5b74152010-11-28 17:18:55 +0000240}
241
Weiming Zhao74a7fa02017-04-03 21:50:04 +0000242void MCObjectStreamer::EmitLabel(MCSymbol *Symbol, SMLoc Loc, MCFragment *F) {
243 MCStreamer::EmitLabel(Symbol, Loc);
244 getAssembler().registerSymbol(*Symbol);
245 auto *DF = dyn_cast_or_null<MCDataFragment>(F);
246 if (DF)
247 Symbol->setFragment(F);
248 else
249 PendingLabels.push_back(Symbol);
250}
251
Rafael Espindola6aea5922011-04-21 23:39:26 +0000252void MCObjectStreamer::EmitULEB128Value(const MCExpr *Value) {
Rafael Espindola675fbb22010-12-03 01:19:49 +0000253 int64_t IntValue;
Nirav Dave6c0665e2018-04-30 19:22:40 +0000254 if (Value->evaluateAsAbsolute(IntValue, getAssemblerPtr())) {
Rafael Espindola6aea5922011-04-21 23:39:26 +0000255 EmitULEB128IntValue(IntValue);
Rafael Espindola675fbb22010-12-03 01:19:49 +0000256 return;
257 }
Peter Collingbourne2f495b92013-04-17 21:18:16 +0000258 insert(new MCLEBFragment(*Value, false));
Rafael Espindola5e874982010-11-02 17:22:24 +0000259}
260
Rafael Espindola6aea5922011-04-21 23:39:26 +0000261void MCObjectStreamer::EmitSLEB128Value(const MCExpr *Value) {
Rafael Espindola675fbb22010-12-03 01:19:49 +0000262 int64_t IntValue;
Nirav Dave6c0665e2018-04-30 19:22:40 +0000263 if (Value->evaluateAsAbsolute(IntValue, getAssemblerPtr())) {
Rafael Espindola6aea5922011-04-21 23:39:26 +0000264 EmitSLEB128IntValue(IntValue);
Rafael Espindola675fbb22010-12-03 01:19:49 +0000265 return;
266 }
Peter Collingbourne2f495b92013-04-17 21:18:16 +0000267 insert(new MCLEBFragment(*Value, true));
Rafael Espindola5e874982010-11-02 17:22:24 +0000268}
269
Rafael Espindola16145972010-11-01 14:28:48 +0000270void MCObjectStreamer::EmitWeakReference(MCSymbol *Alias,
271 const MCSymbol *Symbol) {
272 report_fatal_error("This file format doesn't support weak aliases.");
273}
274
Rafael Espindola0709a7b2015-05-21 19:20:38 +0000275void MCObjectStreamer::ChangeSection(MCSection *Section,
Peter Collingbourne2f495b92013-04-17 21:18:16 +0000276 const MCExpr *Subsection) {
Rafael Espindola36a15cb2015-03-20 20:00:01 +0000277 changeSectionImpl(Section, Subsection);
278}
279
Rafael Espindola0709a7b2015-05-21 19:20:38 +0000280bool MCObjectStreamer::changeSectionImpl(MCSection *Section,
Rafael Espindola36a15cb2015-03-20 20:00:01 +0000281 const MCExpr *Subsection) {
Daniel Dunbarb2347fe2010-06-16 20:04:25 +0000282 assert(Section && "Cannot switch to a null section!");
Derek Schuff5f708e52014-10-22 22:38:06 +0000283 flushPendingLabels(nullptr);
Reid Kleckner2c6430f2018-04-25 23:34:15 +0000284 getContext().clearCVLocSeen();
David Blaikie6c5bbae2017-03-16 00:52:18 +0000285 getContext().clearDwarfLocSeen();
Daniel Dunbarb2347fe2010-06-16 20:04:25 +0000286
Rafael Espindolabb9a71c2015-05-26 15:07:25 +0000287 bool Created = getAssembler().registerSection(*Section);
Peter Collingbourne2f495b92013-04-17 21:18:16 +0000288
289 int64_t IntSubsection = 0;
290 if (Subsection &&
Nirav Dave6c0665e2018-04-30 19:22:40 +0000291 !Subsection->evaluateAsAbsolute(IntSubsection, getAssemblerPtr()))
Peter Collingbourne2f495b92013-04-17 21:18:16 +0000292 report_fatal_error("Cannot evaluate subsection number");
293 if (IntSubsection < 0 || IntSubsection > 8192)
294 report_fatal_error("Subsection number out of range");
295 CurInsertionPoint =
Rafael Espindola2f9bdd82015-05-27 20:52:32 +0000296 Section->getSubsectionInsertionPoint(unsigned(IntSubsection));
Rafael Espindola36a15cb2015-03-20 20:00:01 +0000297 return Created;
Daniel Dunbarb2347fe2010-06-16 20:04:25 +0000298}
299
Eli Benderskyea2824d2012-12-07 17:42:41 +0000300void MCObjectStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) {
Rafael Espindolab5d316b2015-05-29 20:21:02 +0000301 getAssembler().registerSymbol(*Symbol);
Zoran Jovanovic28221d82014-03-20 09:44:49 +0000302 MCStreamer::EmitAssignment(Symbol, Value);
Eli Benderskyea2824d2012-12-07 17:42:41 +0000303}
304
Rafael Espindolacd625182015-05-25 18:34:26 +0000305bool MCObjectStreamer::mayHaveInstructions(MCSection &Sec) const {
306 return Sec.hasInstructions();
307}
308
Rafael Espindola591c6412014-06-25 18:37:33 +0000309void MCObjectStreamer::EmitInstruction(const MCInst &Inst,
Andrew V. Tischenko75745d02017-04-14 07:44:23 +0000310 const MCSubtargetInfo &STI, bool) {
Omer Paparo Bivas2251c792017-10-24 06:16:03 +0000311 getAssembler().getBackend().handleCodePaddingInstructionBegin(Inst);
312 EmitInstructionImpl(Inst, STI);
313 getAssembler().getBackend().handleCodePaddingInstructionEnd(Inst);
314}
315
316void MCObjectStreamer::EmitInstructionImpl(const MCInst &Inst,
317 const MCSubtargetInfo &STI) {
Rafael Espindola591c6412014-06-25 18:37:33 +0000318 MCStreamer::EmitInstruction(Inst, STI);
Rafael Espindola72b54882010-11-01 16:27:31 +0000319
Rafael Espindola983bec62015-05-27 21:04:14 +0000320 MCSection *Sec = getCurrentSectionOnly();
Rafael Espindola3d2aeb22015-05-26 14:48:11 +0000321 Sec->setHasInstructions(true);
Rafael Espindola72b54882010-11-01 16:27:31 +0000322
323 // Now that a machine instruction has been assembled into this section, make
324 // a line entry for any .loc directive that has been seen.
Reid Kleckner2214ed82016-01-29 00:49:42 +0000325 MCCVLineEntry::Make(this);
Eric Christopher445c9522016-10-14 05:47:37 +0000326 MCDwarfLineEntry::Make(this, getCurrentSectionOnly());
Rafael Espindola72b54882010-11-01 16:27:31 +0000327
328 // If this instruction doesn't need relaxation, just emit it as data.
Eli Benderskyf483ff92012-12-20 19:05:53 +0000329 MCAssembler &Assembler = getAssembler();
330 if (!Assembler.getBackend().mayNeedRelaxation(Inst)) {
David Woodhouse6f3c73f2014-01-28 23:12:49 +0000331 EmitInstToData(Inst, STI);
Rafael Espindola72b54882010-11-01 16:27:31 +0000332 return;
333 }
334
Eli Benderskyf483ff92012-12-20 19:05:53 +0000335 // Otherwise, relax and emit it as data if either:
336 // - The RelaxAll flag was passed
337 // - Bundling is enabled and this instruction is inside a bundle-locked
338 // group. We want to emit all such instructions into the same data
339 // fragment.
340 if (Assembler.getRelaxAll() ||
Rafael Espindola3d2aeb22015-05-26 14:48:11 +0000341 (Assembler.isBundlingEnabled() && Sec->isBundleLocked())) {
Rafael Espindola72b54882010-11-01 16:27:31 +0000342 MCInst Relaxed;
Nirav Dave86030622016-07-11 14:23:53 +0000343 getAssembler().getBackend().relaxInstruction(Inst, STI, Relaxed);
Jim Grosbachaba3de92012-01-18 18:52:16 +0000344 while (getAssembler().getBackend().mayNeedRelaxation(Relaxed))
Nirav Dave86030622016-07-11 14:23:53 +0000345 getAssembler().getBackend().relaxInstruction(Relaxed, STI, Relaxed);
David Woodhouse6f3c73f2014-01-28 23:12:49 +0000346 EmitInstToData(Relaxed, STI);
Rafael Espindola72b54882010-11-01 16:27:31 +0000347 return;
348 }
349
350 // Otherwise emit to a separate fragment.
David Woodhouse6f3c73f2014-01-28 23:12:49 +0000351 EmitInstToFragment(Inst, STI);
Rafael Espindola72b54882010-11-01 16:27:31 +0000352}
353
David Woodhouse6f3c73f2014-01-28 23:12:49 +0000354void MCObjectStreamer::EmitInstToFragment(const MCInst &Inst,
355 const MCSubtargetInfo &STI) {
Petr Hosek9e0c8902015-04-12 23:42:25 +0000356 if (getAssembler().getRelaxAll() && getAssembler().isBundlingEnabled())
357 llvm_unreachable("All instructions should have already been relaxed");
358
Eli Benderskyf483ff92012-12-20 19:05:53 +0000359 // Always create a new, separate fragment here, because its size can change
360 // during relaxation.
David Woodhousef5199f62014-01-28 23:12:53 +0000361 MCRelaxableFragment *IF = new MCRelaxableFragment(Inst, STI);
Peter Collingbourne2f495b92013-04-17 21:18:16 +0000362 insert(IF);
Rafael Espindola3fa6fc12010-12-02 05:44:06 +0000363
Eli Friedmanb2545fb2011-04-18 20:54:46 +0000364 SmallString<128> Code;
365 raw_svector_ostream VecOS(Code);
Jim Grosbach91df21f2015-05-15 19:13:16 +0000366 getAssembler().getEmitter().encodeInstruction(Inst, VecOS, IF->getFixups(),
David Woodhouse9784cef2014-01-28 23:13:07 +0000367 STI);
Eli Benderskya31a8942012-12-07 19:13:57 +0000368 IF->getContents().append(Code.begin(), Code.end());
Rafael Espindola3fa6fc12010-12-02 05:44:06 +0000369}
370
Matt Beaumont-Gay5ae72082013-02-15 23:12:33 +0000371#ifndef NDEBUG
Craig Topperd3a34f82013-07-16 01:17:10 +0000372static const char *const BundlingNotImplementedMsg =
Eli Benderskyf483ff92012-12-20 19:05:53 +0000373 "Aligned bundling is not implemented for this object format";
Matt Beaumont-Gay5ae72082013-02-15 23:12:33 +0000374#endif
Eli Benderskyf483ff92012-12-20 19:05:53 +0000375
376void MCObjectStreamer::EmitBundleAlignMode(unsigned AlignPow2) {
377 llvm_unreachable(BundlingNotImplementedMsg);
378}
379
Eli Bendersky802b6282013-01-07 21:51:08 +0000380void MCObjectStreamer::EmitBundleLock(bool AlignToEnd) {
Eli Benderskyf483ff92012-12-20 19:05:53 +0000381 llvm_unreachable(BundlingNotImplementedMsg);
382}
383
384void MCObjectStreamer::EmitBundleUnlock() {
385 llvm_unreachable(BundlingNotImplementedMsg);
386}
387
Ulrich Weigand64f44052013-06-19 21:27:27 +0000388void MCObjectStreamer::EmitDwarfLocDirective(unsigned FileNo, unsigned Line,
389 unsigned Column, unsigned Flags,
390 unsigned Isa,
391 unsigned Discriminator,
392 StringRef FileName) {
393 // In case we see two .loc directives in a row, make sure the
394 // first one gets a line entry.
Eric Christopher445c9522016-10-14 05:47:37 +0000395 MCDwarfLineEntry::Make(this, getCurrentSectionOnly());
Ulrich Weigand64f44052013-06-19 21:27:27 +0000396
397 this->MCStreamer::EmitDwarfLocDirective(FileNo, Line, Column, Flags,
398 Isa, Discriminator, FileName);
399}
400
Rafael Espindola38518082014-08-15 14:31:47 +0000401static const MCExpr *buildSymbolDiff(MCObjectStreamer &OS, const MCSymbol *A,
402 const MCSymbol *B) {
403 MCContext &Context = OS.getContext();
404 MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
Jim Grosbach13760bd2015-05-30 01:25:56 +0000405 const MCExpr *ARef = MCSymbolRefExpr::create(A, Variant, Context);
406 const MCExpr *BRef = MCSymbolRefExpr::create(B, Variant, Context);
Rafael Espindola38518082014-08-15 14:31:47 +0000407 const MCExpr *AddrDelta =
Jim Grosbach13760bd2015-05-30 01:25:56 +0000408 MCBinaryExpr::create(MCBinaryExpr::Sub, ARef, BRef, Context);
Rafael Espindola38518082014-08-15 14:31:47 +0000409 return AddrDelta;
410}
411
Frederic Rissa5ab8442015-08-07 15:14:08 +0000412static void emitDwarfSetLineAddr(MCObjectStreamer &OS,
413 MCDwarfLineTableParams Params,
414 int64_t LineDelta, const MCSymbol *Label,
415 int PointerSize) {
Rafael Espindola5e955fb2014-08-15 14:43:02 +0000416 // emit the sequence to set the address
417 OS.EmitIntValue(dwarf::DW_LNS_extended_op, 1);
418 OS.EmitULEB128IntValue(PointerSize + 1);
419 OS.EmitIntValue(dwarf::DW_LNE_set_address, 1);
420 OS.EmitSymbolValue(Label, PointerSize);
421
422 // emit the sequence for the LineDelta (from 1) and a zero address delta.
Frederic Rissa5ab8442015-08-07 15:14:08 +0000423 MCDwarfLineAddr::Emit(&OS, Params, LineDelta, 0);
Rafael Espindola5e955fb2014-08-15 14:43:02 +0000424}
425
Rafael Espindola57ab7082010-12-03 00:55:40 +0000426void MCObjectStreamer::EmitDwarfAdvanceLineAddr(int64_t LineDelta,
427 const MCSymbol *LastLabel,
Evan Chengc7ac6902011-07-14 05:43:07 +0000428 const MCSymbol *Label,
429 unsigned PointerSize) {
Rafael Espindola57ab7082010-12-03 00:55:40 +0000430 if (!LastLabel) {
Frederic Rissa5ab8442015-08-07 15:14:08 +0000431 emitDwarfSetLineAddr(*this, Assembler->getDWARFLinetableParams(), LineDelta,
432 Label, PointerSize);
Rafael Espindola57ab7082010-12-03 00:55:40 +0000433 return;
434 }
Rafael Espindola38518082014-08-15 14:31:47 +0000435 const MCExpr *AddrDelta = buildSymbolDiff(*this, Label, LastLabel);
Rafael Espindola57ab7082010-12-03 00:55:40 +0000436 int64_t Res;
Nirav Dave6c0665e2018-04-30 19:22:40 +0000437 if (AddrDelta->evaluateAsAbsolute(Res, getAssemblerPtr())) {
Frederic Rissa5ab8442015-08-07 15:14:08 +0000438 MCDwarfLineAddr::Emit(this, Assembler->getDWARFLinetableParams(), LineDelta,
439 Res);
Rafael Espindola57ab7082010-12-03 00:55:40 +0000440 return;
441 }
Peter Collingbourne2f495b92013-04-17 21:18:16 +0000442 insert(new MCDwarfLineAddrFragment(LineDelta, *AddrDelta));
Rafael Espindola57ab7082010-12-03 00:55:40 +0000443}
444
Rafael Espindola736a35d2010-12-28 05:39:27 +0000445void MCObjectStreamer::EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel,
446 const MCSymbol *Label) {
Rafael Espindola38518082014-08-15 14:31:47 +0000447 const MCExpr *AddrDelta = buildSymbolDiff(*this, Label, LastLabel);
Rafael Espindola736a35d2010-12-28 05:39:27 +0000448 int64_t Res;
Nirav Dave6c0665e2018-04-30 19:22:40 +0000449 if (AddrDelta->evaluateAsAbsolute(Res, getAssemblerPtr())) {
Rafael Espindola736a35d2010-12-28 05:39:27 +0000450 MCDwarfFrameEmitter::EmitAdvanceLoc(*this, Res);
451 return;
452 }
Peter Collingbourne2f495b92013-04-17 21:18:16 +0000453 insert(new MCDwarfCallFrameFragment(*AddrDelta));
Rafael Espindola736a35d2010-12-28 05:39:27 +0000454}
455
Reid Kleckner2214ed82016-01-29 00:49:42 +0000456void MCObjectStreamer::EmitCVLocDirective(unsigned FunctionId, unsigned FileNo,
457 unsigned Line, unsigned Column,
458 bool PrologueEnd, bool IsStmt,
Reid Klecknera9f4cc92016-09-07 16:15:31 +0000459 StringRef FileName, SMLoc Loc) {
Reid Kleckner2214ed82016-01-29 00:49:42 +0000460 // In case we see two .cv_loc directives in a row, make sure the
461 // first one gets a line entry.
462 MCCVLineEntry::Make(this);
463
464 this->MCStreamer::EmitCVLocDirective(FunctionId, FileNo, Line, Column,
Reid Klecknera9f4cc92016-09-07 16:15:31 +0000465 PrologueEnd, IsStmt, FileName, Loc);
Reid Kleckner2214ed82016-01-29 00:49:42 +0000466}
467
468void MCObjectStreamer::EmitCVLinetableDirective(unsigned FunctionId,
469 const MCSymbol *Begin,
470 const MCSymbol *End) {
471 getContext().getCVContext().emitLineTableForFunction(*this, FunctionId, Begin,
472 End);
473 this->MCStreamer::EmitCVLinetableDirective(FunctionId, Begin, End);
474}
475
David Majnemer6fcbd7e2016-01-29 19:24:12 +0000476void MCObjectStreamer::EmitCVInlineLinetableDirective(
477 unsigned PrimaryFunctionId, unsigned SourceFileId, unsigned SourceLineNum,
Reid Klecknera9f4cc92016-09-07 16:15:31 +0000478 const MCSymbol *FnStartSym, const MCSymbol *FnEndSym) {
David Majnemer6fcbd7e2016-01-29 19:24:12 +0000479 getContext().getCVContext().emitInlineLineTableForFunction(
Reid Kleckner1fcd6102016-02-02 17:41:18 +0000480 *this, PrimaryFunctionId, SourceFileId, SourceLineNum, FnStartSym,
Reid Klecknera9f4cc92016-09-07 16:15:31 +0000481 FnEndSym);
David Majnemer6fcbd7e2016-01-29 19:24:12 +0000482 this->MCStreamer::EmitCVInlineLinetableDirective(
Reid Klecknera9f4cc92016-09-07 16:15:31 +0000483 PrimaryFunctionId, SourceFileId, SourceLineNum, FnStartSym, FnEndSym);
David Majnemer6fcbd7e2016-01-29 19:24:12 +0000484}
485
David Majnemer408b5e62016-02-05 01:55:49 +0000486void MCObjectStreamer::EmitCVDefRangeDirective(
487 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
488 StringRef FixedSizePortion) {
489 getContext().getCVContext().emitDefRange(*this, Ranges, FixedSizePortion);
490 this->MCStreamer::EmitCVDefRangeDirective(Ranges, FixedSizePortion);
491}
492
Reid Kleckner2214ed82016-01-29 00:49:42 +0000493void MCObjectStreamer::EmitCVStringTableDirective() {
494 getContext().getCVContext().emitStringTable(*this);
495}
496void MCObjectStreamer::EmitCVFileChecksumsDirective() {
497 getContext().getCVContext().emitFileChecksums(*this);
498}
499
Reid Kleckner26fa1bf2017-09-19 18:14:45 +0000500void MCObjectStreamer::EmitCVFileChecksumOffsetDirective(unsigned FileNo) {
501 getContext().getCVContext().emitFileChecksumOffset(*this, FileNo);
502}
Reid Kleckner2214ed82016-01-29 00:49:42 +0000503
Rafael Espindola64e1af82013-07-02 15:49:13 +0000504void MCObjectStreamer::EmitBytes(StringRef Data) {
Reid Kleckner2214ed82016-01-29 00:49:42 +0000505 MCCVLineEntry::Make(this);
Eric Christopher445c9522016-10-14 05:47:37 +0000506 MCDwarfLineEntry::Make(this, getCurrentSectionOnly());
Petr Hosek32946702015-06-27 01:54:17 +0000507 MCDataFragment *DF = getOrCreateDataFragment();
508 flushPendingLabels(DF, DF->getContents().size());
509 DF->getContents().append(Data.begin(), Data.end());
Benjamin Kramer64ddcb02012-10-04 13:12:43 +0000510}
511
512void MCObjectStreamer::EmitValueToAlignment(unsigned ByteAlignment,
513 int64_t Value,
514 unsigned ValueSize,
515 unsigned MaxBytesToEmit) {
516 if (MaxBytesToEmit == 0)
517 MaxBytesToEmit = ByteAlignment;
Peter Collingbourne2f495b92013-04-17 21:18:16 +0000518 insert(new MCAlignFragment(ByteAlignment, Value, ValueSize, MaxBytesToEmit));
Benjamin Kramer64ddcb02012-10-04 13:12:43 +0000519
520 // Update the maximum alignment on the current section if necessary.
Eric Christopher445c9522016-10-14 05:47:37 +0000521 MCSection *CurSec = getCurrentSectionOnly();
Rafael Espindola967d6a62015-05-21 21:02:35 +0000522 if (ByteAlignment > CurSec->getAlignment())
523 CurSec->setAlignment(ByteAlignment);
Benjamin Kramer64ddcb02012-10-04 13:12:43 +0000524}
525
526void MCObjectStreamer::EmitCodeAlignment(unsigned ByteAlignment,
527 unsigned MaxBytesToEmit) {
528 EmitValueToAlignment(ByteAlignment, 0, 1, MaxBytesToEmit);
529 cast<MCAlignFragment>(getCurrentFragment())->setEmitNops(true);
530}
531
Rafael Espindola7ae65d82015-11-04 23:59:18 +0000532void MCObjectStreamer::emitValueToOffset(const MCExpr *Offset,
Oliver Stannard268f42f2016-12-14 10:43:58 +0000533 unsigned char Value,
534 SMLoc Loc) {
535 insert(new MCOrgFragment(*Offset, Value, Loc));
Rafael Espindola9065bfc62010-12-02 05:59:38 +0000536}
537
Omer Paparo Bivas2251c792017-10-24 06:16:03 +0000538void MCObjectStreamer::EmitCodePaddingBasicBlockStart(
539 const MCCodePaddingContext &Context) {
540 getAssembler().getBackend().handleCodePaddingBasicBlockStart(this, Context);
541}
542
543void MCObjectStreamer::EmitCodePaddingBasicBlockEnd(
544 const MCCodePaddingContext &Context) {
545 getAssembler().getBackend().handleCodePaddingBasicBlockEnd(Context);
546}
547
Simon Atanasyaneb9ed612016-08-22 16:18:42 +0000548// Associate DTPRel32 fixup with data and resize data area
549void MCObjectStreamer::EmitDTPRel32Value(const MCExpr *Value) {
550 MCDataFragment *DF = getOrCreateDataFragment();
551 flushPendingLabels(DF, DF->getContents().size());
552
553 DF->getFixups().push_back(MCFixup::create(DF->getContents().size(),
554 Value, FK_DTPRel_4));
555 DF->getContents().resize(DF->getContents().size() + 4, 0);
556}
557
558// Associate DTPRel64 fixup with data and resize data area
559void MCObjectStreamer::EmitDTPRel64Value(const MCExpr *Value) {
560 MCDataFragment *DF = getOrCreateDataFragment();
561 flushPendingLabels(DF, DF->getContents().size());
562
563 DF->getFixups().push_back(MCFixup::create(DF->getContents().size(),
564 Value, FK_DTPRel_8));
565 DF->getContents().resize(DF->getContents().size() + 8, 0);
566}
567
568// Associate TPRel32 fixup with data and resize data area
569void MCObjectStreamer::EmitTPRel32Value(const MCExpr *Value) {
570 MCDataFragment *DF = getOrCreateDataFragment();
571 flushPendingLabels(DF, DF->getContents().size());
572
573 DF->getFixups().push_back(MCFixup::create(DF->getContents().size(),
574 Value, FK_TPRel_4));
575 DF->getContents().resize(DF->getContents().size() + 4, 0);
576}
577
578// Associate TPRel64 fixup with data and resize data area
579void MCObjectStreamer::EmitTPRel64Value(const MCExpr *Value) {
580 MCDataFragment *DF = getOrCreateDataFragment();
581 flushPendingLabels(DF, DF->getContents().size());
582
583 DF->getFixups().push_back(MCFixup::create(DF->getContents().size(),
584 Value, FK_TPRel_8));
585 DF->getContents().resize(DF->getContents().size() + 8, 0);
586}
587
Akira Hatanakaf5ddf132011-11-23 22:18:04 +0000588// Associate GPRel32 fixup with data and resize data area
589void MCObjectStreamer::EmitGPRel32Value(const MCExpr *Value) {
590 MCDataFragment *DF = getOrCreateDataFragment();
Petr Hosek32946702015-06-27 01:54:17 +0000591 flushPendingLabels(DF, DF->getContents().size());
Akira Hatanakaf5ddf132011-11-23 22:18:04 +0000592
Weiming Zhao74a7fa02017-04-03 21:50:04 +0000593 DF->getFixups().push_back(
594 MCFixup::create(DF->getContents().size(), Value, FK_GPRel_4));
Akira Hatanakaf5ddf132011-11-23 22:18:04 +0000595 DF->getContents().resize(DF->getContents().size() + 4, 0);
596}
597
Simon Atanasyaneb9ed612016-08-22 16:18:42 +0000598// Associate GPRel64 fixup with data and resize data area
Jack Carter77064c02012-08-22 00:49:30 +0000599void MCObjectStreamer::EmitGPRel64Value(const MCExpr *Value) {
600 MCDataFragment *DF = getOrCreateDataFragment();
Petr Hosek32946702015-06-27 01:54:17 +0000601 flushPendingLabels(DF, DF->getContents().size());
Jack Carter77064c02012-08-22 00:49:30 +0000602
Weiming Zhao74a7fa02017-04-03 21:50:04 +0000603 DF->getFixups().push_back(
604 MCFixup::create(DF->getContents().size(), Value, FK_GPRel_4));
Jack Carter77064c02012-08-22 00:49:30 +0000605 DF->getContents().resize(DF->getContents().size() + 8, 0);
606}
607
Daniel Sanders9f6ad492015-11-12 13:33:00 +0000608bool MCObjectStreamer::EmitRelocDirective(const MCExpr &Offset, StringRef Name,
609 const MCExpr *Expr, SMLoc Loc) {
610 int64_t OffsetValue;
611 if (!Offset.evaluateAsAbsolute(OffsetValue))
612 llvm_unreachable("Offset is not absolute");
613
David Majnemerce108422016-01-19 23:05:27 +0000614 if (OffsetValue < 0)
615 llvm_unreachable("Offset is negative");
616
Daniel Sanders9f6ad492015-11-12 13:33:00 +0000617 MCDataFragment *DF = getOrCreateDataFragment();
618 flushPendingLabels(DF, DF->getContents().size());
619
David Majnemerce108422016-01-19 23:05:27 +0000620 Optional<MCFixupKind> MaybeKind = Assembler->getBackend().getFixupKind(Name);
621 if (!MaybeKind.hasValue())
Daniel Sanders9f6ad492015-11-12 13:33:00 +0000622 return true;
623
David Majnemerce108422016-01-19 23:05:27 +0000624 MCFixupKind Kind = *MaybeKind;
625
Daniel Sanders9f6ad492015-11-12 13:33:00 +0000626 if (Expr == nullptr)
627 Expr =
628 MCSymbolRefExpr::create(getContext().createTempSymbol(), getContext());
629 DF->getFixups().push_back(MCFixup::create(OffsetValue, Expr, Kind, Loc));
630 return false;
631}
632
Petr Hosek67a94a72016-05-28 05:57:48 +0000633void MCObjectStreamer::emitFill(const MCExpr &NumBytes, uint64_t FillValue,
634 SMLoc Loc) {
635 MCDataFragment *DF = getOrCreateDataFragment();
636 flushPendingLabels(DF, DF->getContents().size());
637
Rafael Espindola8fcd07d2018-01-09 19:29:33 +0000638 assert(getCurrentSectionOnly() && "need a section");
Nirav Dave588fad42018-05-18 17:45:48 +0000639 insert(new MCFillFragment(FillValue, 1, NumBytes, Loc));
Petr Hosek67a94a72016-05-28 05:57:48 +0000640}
641
642void MCObjectStreamer::emitFill(const MCExpr &NumValues, int64_t Size,
643 int64_t Expr, SMLoc Loc) {
644 int64_t IntNumValues;
Nirav Dave588fad42018-05-18 17:45:48 +0000645 // Do additional checking now if we can resolve the value.
646 if (NumValues.evaluateAsAbsolute(IntNumValues, getAssemblerPtr())) {
647 if (IntNumValues < 0) {
648 getContext().getSourceManager()->PrintMessage(
649 Loc, SourceMgr::DK_Warning,
650 "'.fill' directive with negative repeat count has no effect");
651 return;
652 }
653 // Emit now if we can for better errors.
654 int64_t NonZeroSize = Size > 4 ? 4 : Size;
655 Expr &= ~0ULL >> (64 - NonZeroSize * 8);
656 for (uint64_t i = 0, e = IntNumValues; i != e; ++i) {
657 EmitIntValue(Expr, NonZeroSize);
658 if (NonZeroSize < Size)
659 EmitIntValue(0, Size - NonZeroSize);
660 }
Petr Hosek67a94a72016-05-28 05:57:48 +0000661 return;
662 }
663
Nirav Dave588fad42018-05-18 17:45:48 +0000664 // Otherwise emit as fragment.
665 MCDataFragment *DF = getOrCreateDataFragment();
666 flushPendingLabels(DF, DF->getContents().size());
Petr Hosek67a94a72016-05-28 05:57:48 +0000667
Nirav Dave588fad42018-05-18 17:45:48 +0000668 assert(getCurrentSectionOnly() && "need a section");
669 insert(new MCFillFragment(Expr, Size, NumValues, Loc));
Petr Hosek67a94a72016-05-28 05:57:48 +0000670}
671
Peter Collingbourne5b75fd92017-03-03 21:22:06 +0000672void MCObjectStreamer::EmitFileDirective(StringRef Filename) {
673 getAssembler().addFileName(Filename);
674}
675
Rafael Espindola07082092012-01-07 03:13:18 +0000676void MCObjectStreamer::FinishImpl() {
Kevin Enderbye7739d42011-12-09 18:09:40 +0000677 // If we are generating dwarf for assembly source files dump out the sections.
678 if (getContext().getGenDwarfForAssembly())
David Blaikie8bf66c42014-04-01 07:35:52 +0000679 MCGenDwarfInfo::Emit(this);
680
681 // Dump out the dwarf file & directory tables and line tables.
Frederic Rissa5ab8442015-08-07 15:14:08 +0000682 MCDwarfLineTable::Emit(this, getAssembler().getDWARFLinetableParams());
Kevin Enderbye7739d42011-12-09 18:09:40 +0000683
Derek Schuff5f708e52014-10-22 22:38:06 +0000684 flushPendingLabels(nullptr);
Daniel Dunbarb2347fe2010-06-16 20:04:25 +0000685 getAssembler().Finish();
686}