Line data Source code
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/MCAssembler.h"
14 : #include "llvm/MC/MCCodeEmitter.h"
15 : #include "llvm/MC/MCCodeView.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/MCSection.h"
21 : #include "llvm/MC/MCSymbol.h"
22 : #include "llvm/Support/ErrorHandling.h"
23 : #include "llvm/Support/SourceMgr.h"
24 : using namespace llvm;
25 :
26 12469 : MCObjectStreamer::MCObjectStreamer(MCContext &Context,
27 : std::unique_ptr<MCAsmBackend> TAB,
28 : std::unique_ptr<MCObjectWriter> OW,
29 12469 : std::unique_ptr<MCCodeEmitter> Emitter)
30 : : MCStreamer(Context),
31 : Assembler(llvm::make_unique<MCAssembler>(
32 : Context, std::move(TAB), std::move(Emitter), std::move(OW))),
33 12469 : EmitEHFrame(true), EmitDebugFrame(false) {}
34 :
35 16270 : MCObjectStreamer::~MCObjectStreamer() {}
36 :
37 : // 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.
40 3983670 : MCAssembler *MCObjectStreamer::getAssemblerPtr() {
41 3983670 : if (getUseAssemblerInfoForParsing())
42 17386 : return Assembler.get();
43 : return nullptr;
44 : }
45 :
46 20228308 : void MCObjectStreamer::flushPendingLabels(MCFragment *F, uint64_t FOffset) {
47 20228308 : if (PendingLabels.empty())
48 : return;
49 758943 : if (!F) {
50 10053 : F = new MCDataFragment();
51 : MCSection *CurSection = getCurrentSectionOnly();
52 : CurSection->getFragmentList().insert(CurInsertionPoint, F);
53 : F->setParent(CurSection);
54 : }
55 1966354 : for (MCSymbol *Sym : PendingLabels) {
56 : Sym->setFragment(F);
57 : Sym->setOffset(FOffset);
58 : }
59 : PendingLabels.clear();
60 : }
61 :
62 : // As a compile-time optimization, avoid allocating and evaluating an MCExpr
63 : // tree for (Hi - Lo) when Hi and Lo are offsets into the same fragment.
64 : static Optional<uint64_t>
65 1654996 : absoluteSymbolDiff(MCAssembler &Asm, const MCSymbol *Hi, const MCSymbol *Lo) {
66 : assert(Hi && Lo);
67 1654996 : if (Asm.getBackendPtr()->requiresDiffExpressionRelocations())
68 : return None;
69 :
70 3232021 : if (!Hi->getFragment() || Hi->getFragment() != Lo->getFragment() ||
71 3105112 : Hi->isVariable() || Lo->isVariable())
72 : return None;
73 :
74 1450091 : return Hi->getOffset() - Lo->getOffset();
75 : }
76 :
77 99356 : void MCObjectStreamer::emitAbsoluteSymbolDiff(const MCSymbol *Hi,
78 : const MCSymbol *Lo,
79 : unsigned Size) {
80 99356 : if (Optional<uint64_t> Diff = absoluteSymbolDiff(getAssembler(), Hi, Lo)) {
81 58390 : EmitIntValue(*Diff, Size);
82 : return;
83 : }
84 40967 : MCStreamer::emitAbsoluteSymbolDiff(Hi, Lo, Size);
85 : }
86 :
87 1555639 : void MCObjectStreamer::emitAbsoluteSymbolDiffAsULEB128(const MCSymbol *Hi,
88 : const MCSymbol *Lo) {
89 1555639 : if (Optional<uint64_t> Diff = absoluteSymbolDiff(getAssembler(), Hi, Lo)) {
90 1391701 : EmitULEB128IntValue(*Diff);
91 : return;
92 : }
93 163938 : MCStreamer::emitAbsoluteSymbolDiffAsULEB128(Hi, Lo);
94 : }
95 :
96 8140 : void MCObjectStreamer::reset() {
97 8140 : if (Assembler)
98 8140 : Assembler->reset();
99 8140 : CurInsertionPoint = MCSection::iterator();
100 8140 : EmitEHFrame = true;
101 8140 : EmitDebugFrame = false;
102 : PendingLabels.clear();
103 8140 : MCStreamer::reset();
104 8140 : }
105 :
106 12356 : void MCObjectStreamer::EmitFrames(MCAsmBackend *MAB) {
107 12356 : if (!getNumFrameInfos())
108 : return;
109 :
110 6991 : if (EmitEHFrame)
111 6892 : MCDwarfFrameEmitter::Emit(*this, MAB, true);
112 :
113 6991 : if (EmitDebugFrame)
114 99 : MCDwarfFrameEmitter::Emit(*this, MAB, false);
115 : }
116 :
117 82404031 : MCFragment *MCObjectStreamer::getCurrentFragment() const {
118 : assert(getCurrentSectionOnly() && "No current section!");
119 :
120 82404031 : if (CurInsertionPoint != getCurrentSectionOnly()->getFragmentList().begin())
121 : return &*std::prev(CurInsertionPoint);
122 :
123 : return nullptr;
124 : }
125 :
126 : static bool CanReuseDataFragment(const MCDataFragment &F,
127 : const MCAssembler &Assembler,
128 : const MCSubtargetInfo *STI) {
129 41533764 : if (!F.hasInstructions())
130 : return true;
131 : // When bundling is enabled, we don't want to add data to a fragment that
132 : // already has instructions (see MCELFStreamer::EmitInstToData for details)
133 30182871 : if (Assembler.isBundlingEnabled())
134 : return Assembler.getRelaxAll();
135 : // If the subtarget is changed mid fragment we start a new fragment to record
136 : // the new STI.
137 30182745 : return !STI || F.getSubtargetInfo() == STI;
138 : }
139 :
140 : MCDataFragment *
141 44111480 : MCObjectStreamer::getOrCreateDataFragment(const MCSubtargetInfo *STI) {
142 44111480 : MCDataFragment *F = dyn_cast_or_null<MCDataFragment>(getCurrentFragment());
143 126 : if (!F || !CanReuseDataFragment(*F, *Assembler, STI)) {
144 2577775 : F = new MCDataFragment();
145 2577775 : insert(F);
146 : }
147 44111480 : return F;
148 : }
149 :
150 0 : MCPaddingFragment *MCObjectStreamer::getOrCreatePaddingFragment() {
151 : MCPaddingFragment *F =
152 0 : dyn_cast_or_null<MCPaddingFragment>(getCurrentFragment());
153 : if (!F) {
154 0 : F = new MCPaddingFragment();
155 0 : insert(F);
156 : }
157 0 : return F;
158 : }
159 :
160 8765327 : void MCObjectStreamer::visitUsedSymbol(const MCSymbol &Sym) {
161 8765327 : Assembler->registerSymbol(Sym);
162 8765327 : }
163 :
164 100 : void MCObjectStreamer::EmitCFISections(bool EH, bool Debug) {
165 100 : MCStreamer::EmitCFISections(EH, Debug);
166 100 : EmitEHFrame = EH;
167 100 : EmitDebugFrame = Debug;
168 100 : }
169 :
170 2249943 : void MCObjectStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size,
171 : SMLoc Loc) {
172 2249943 : MCStreamer::EmitValueImpl(Value, Size, Loc);
173 2249944 : MCDataFragment *DF = getOrCreateDataFragment();
174 4499888 : flushPendingLabels(DF, DF->getContents().size());
175 :
176 2249944 : MCDwarfLineEntry::Make(this, getCurrentSectionOnly());
177 :
178 : // Avoid fixups when possible.
179 : int64_t AbsValue;
180 2249944 : if (Value->evaluateAsAbsolute(AbsValue, getAssemblerPtr())) {
181 14357 : if (!isUIntN(8 * Size, AbsValue) && !isIntN(8 * Size, AbsValue)) {
182 2 : getContext().reportError(
183 1 : Loc, "value evaluated as " + Twine(AbsValue) + " is out of range.");
184 14357 : return;
185 : }
186 14356 : EmitIntValue(AbsValue, Size);
187 14356 : return;
188 : }
189 4470920 : DF->getFixups().push_back(
190 2235587 : MCFixup::create(DF->getContents().size(), Value,
191 : MCFixup::getKindForSize(Size, false), Loc));
192 4471174 : DF->getContents().resize(DF->getContents().size() + Size, 0);
193 : }
194 :
195 941015 : MCSymbol *MCObjectStreamer::EmitCFILabel() {
196 1882030 : MCSymbol *Label = getContext().createTempSymbol("cfi", true);
197 941015 : EmitLabel(Label);
198 941015 : return Label;
199 : }
200 :
201 208012 : void MCObjectStreamer::EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) {
202 : // We need to create a local symbol to avoid relocations.
203 208012 : Frame.Begin = getContext().createTempSymbol();
204 208012 : EmitLabel(Frame.Begin);
205 208012 : }
206 :
207 208011 : void MCObjectStreamer::EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) {
208 208011 : Frame.End = getContext().createTempSymbol();
209 208011 : EmitLabel(Frame.End);
210 208011 : }
211 :
212 7789558 : void MCObjectStreamer::EmitLabel(MCSymbol *Symbol, SMLoc Loc) {
213 7789558 : MCStreamer::EmitLabel(Symbol, Loc);
214 :
215 7789559 : getAssembler().registerSymbol(*Symbol);
216 :
217 : // If there is a current fragment, mark the symbol as pointing into it.
218 : // Otherwise queue the label and set its fragment pointer when we emit the
219 : // next fragment.
220 7789560 : auto *F = dyn_cast_or_null<MCDataFragment>(getCurrentFragment());
221 6582155 : if (F && !(getAssembler().isBundlingEnabled() &&
222 : getAssembler().getRelaxAll())) {
223 6582140 : Symbol->setFragment(F);
224 6582140 : Symbol->setOffset(F->getContents().size());
225 : } else {
226 1207420 : PendingLabels.push_back(Symbol);
227 : }
228 7789560 : }
229 :
230 10 : void MCObjectStreamer::EmitLabel(MCSymbol *Symbol, SMLoc Loc, MCFragment *F) {
231 10 : MCStreamer::EmitLabel(Symbol, Loc);
232 10 : getAssembler().registerSymbol(*Symbol);
233 : auto *DF = dyn_cast_or_null<MCDataFragment>(F);
234 : if (DF)
235 10 : Symbol->setFragment(F);
236 : else
237 0 : PendingLabels.push_back(Symbol);
238 10 : }
239 :
240 164211 : void MCObjectStreamer::EmitULEB128Value(const MCExpr *Value) {
241 : int64_t IntValue;
242 164211 : if (Value->evaluateAsAbsolute(IntValue, getAssemblerPtr())) {
243 263 : EmitULEB128IntValue(IntValue);
244 263 : return;
245 : }
246 163948 : insert(new MCLEBFragment(*Value, false));
247 : }
248 :
249 57 : void MCObjectStreamer::EmitSLEB128Value(const MCExpr *Value) {
250 : int64_t IntValue;
251 57 : if (Value->evaluateAsAbsolute(IntValue, getAssemblerPtr())) {
252 55 : EmitSLEB128IntValue(IntValue);
253 55 : return;
254 : }
255 2 : insert(new MCLEBFragment(*Value, true));
256 : }
257 :
258 0 : void MCObjectStreamer::EmitWeakReference(MCSymbol *Alias,
259 : const MCSymbol *Symbol) {
260 0 : report_fatal_error("This file format doesn't support weak aliases.");
261 : }
262 :
263 3941 : void MCObjectStreamer::ChangeSection(MCSection *Section,
264 : const MCExpr *Subsection) {
265 3941 : changeSectionImpl(Section, Subsection);
266 3941 : }
267 :
268 803448 : bool MCObjectStreamer::changeSectionImpl(MCSection *Section,
269 : const MCExpr *Subsection) {
270 : assert(Section && "Cannot switch to a null section!");
271 803448 : flushPendingLabels(nullptr);
272 803449 : getContext().clearDwarfLocSeen();
273 :
274 803449 : bool Created = getAssembler().registerSection(*Section);
275 :
276 803449 : int64_t IntSubsection = 0;
277 803455 : if (Subsection &&
278 6 : !Subsection->evaluateAsAbsolute(IntSubsection, getAssemblerPtr()))
279 0 : report_fatal_error("Cannot evaluate subsection number");
280 803449 : if (IntSubsection < 0 || IntSubsection > 8192)
281 0 : report_fatal_error("Subsection number out of range");
282 : CurInsertionPoint =
283 803449 : Section->getSubsectionInsertionPoint(unsigned(IntSubsection));
284 803449 : return Created;
285 : }
286 :
287 5821 : void MCObjectStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) {
288 5821 : getAssembler().registerSymbol(*Symbol);
289 5821 : MCStreamer::EmitAssignment(Symbol, Value);
290 5821 : }
291 :
292 40 : bool MCObjectStreamer::mayHaveInstructions(MCSection &Sec) const {
293 40 : return Sec.hasInstructions();
294 : }
295 :
296 30185752 : void MCObjectStreamer::EmitInstruction(const MCInst &Inst,
297 : const MCSubtargetInfo &STI, bool) {
298 30185752 : getAssembler().getBackend().handleCodePaddingInstructionBegin(Inst);
299 30185752 : EmitInstructionImpl(Inst, STI);
300 30185749 : getAssembler().getBackend().handleCodePaddingInstructionEnd(Inst);
301 30185749 : }
302 :
303 30185752 : void MCObjectStreamer::EmitInstructionImpl(const MCInst &Inst,
304 : const MCSubtargetInfo &STI) {
305 30185752 : MCStreamer::EmitInstruction(Inst, STI);
306 :
307 : MCSection *Sec = getCurrentSectionOnly();
308 : Sec->setHasInstructions(true);
309 :
310 : // Now that a machine instruction has been assembled into this section, make
311 : // a line entry for any .loc directive that has been seen.
312 30185752 : MCDwarfLineEntry::Make(this, getCurrentSectionOnly());
313 :
314 : // If this instruction doesn't need relaxation, just emit it as data.
315 : MCAssembler &Assembler = getAssembler();
316 30185752 : if (!Assembler.getBackend().mayNeedRelaxation(Inst, STI)) {
317 28085699 : EmitInstToData(Inst, STI);
318 28085696 : return;
319 : }
320 :
321 : // Otherwise, relax and emit it as data if either:
322 : // - The RelaxAll flag was passed
323 : // - Bundling is enabled and this instruction is inside a bundle-locked
324 : // group. We want to emit all such instructions into the same data
325 : // fragment.
326 2100053 : if (Assembler.getRelaxAll() ||
327 128057 : (Assembler.isBundlingEnabled() && Sec->isBundleLocked())) {
328 : MCInst Relaxed;
329 1971998 : getAssembler().getBackend().relaxInstruction(Inst, STI, Relaxed);
330 1971998 : while (getAssembler().getBackend().mayNeedRelaxation(Relaxed, STI))
331 0 : getAssembler().getBackend().relaxInstruction(Relaxed, STI, Relaxed);
332 1971998 : EmitInstToData(Relaxed, STI);
333 : return;
334 : }
335 :
336 : // Otherwise emit to a separate fragment.
337 128055 : EmitInstToFragment(Inst, STI);
338 : }
339 :
340 128055 : void MCObjectStreamer::EmitInstToFragment(const MCInst &Inst,
341 : const MCSubtargetInfo &STI) {
342 128055 : if (getAssembler().getRelaxAll() && getAssembler().isBundlingEnabled())
343 0 : llvm_unreachable("All instructions should have already been relaxed");
344 :
345 : // Always create a new, separate fragment here, because its size can change
346 : // during relaxation.
347 128055 : MCRelaxableFragment *IF = new MCRelaxableFragment(Inst, STI);
348 128055 : insert(IF);
349 :
350 : SmallString<128> Code;
351 : raw_svector_ostream VecOS(Code);
352 128055 : getAssembler().getEmitter().encodeInstruction(Inst, VecOS, IF->getFixups(),
353 128055 : STI);
354 128055 : IF->getContents().append(Code.begin(), Code.end());
355 128055 : }
356 :
357 : #ifndef NDEBUG
358 : static const char *const BundlingNotImplementedMsg =
359 : "Aligned bundling is not implemented for this object format";
360 : #endif
361 :
362 0 : void MCObjectStreamer::EmitBundleAlignMode(unsigned AlignPow2) {
363 0 : llvm_unreachable(BundlingNotImplementedMsg);
364 : }
365 :
366 0 : void MCObjectStreamer::EmitBundleLock(bool AlignToEnd) {
367 0 : llvm_unreachable(BundlingNotImplementedMsg);
368 : }
369 :
370 0 : void MCObjectStreamer::EmitBundleUnlock() {
371 0 : llvm_unreachable(BundlingNotImplementedMsg);
372 : }
373 :
374 620952 : void MCObjectStreamer::EmitDwarfLocDirective(unsigned FileNo, unsigned Line,
375 : unsigned Column, unsigned Flags,
376 : unsigned Isa,
377 : unsigned Discriminator,
378 : StringRef FileName) {
379 : // In case we see two .loc directives in a row, make sure the
380 : // first one gets a line entry.
381 620952 : MCDwarfLineEntry::Make(this, getCurrentSectionOnly());
382 :
383 620952 : this->MCStreamer::EmitDwarfLocDirective(FileNo, Line, Column, Flags,
384 : Isa, Discriminator, FileName);
385 620952 : }
386 :
387 1561448 : static const MCExpr *buildSymbolDiff(MCObjectStreamer &OS, const MCSymbol *A,
388 : const MCSymbol *B) {
389 1561448 : MCContext &Context = OS.getContext();
390 : MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
391 1561448 : const MCExpr *ARef = MCSymbolRefExpr::create(A, Variant, Context);
392 1561448 : const MCExpr *BRef = MCSymbolRefExpr::create(B, Variant, Context);
393 : const MCExpr *AddrDelta =
394 1561448 : MCBinaryExpr::create(MCBinaryExpr::Sub, ARef, BRef, Context);
395 1561448 : return AddrDelta;
396 : }
397 :
398 8072 : static void emitDwarfSetLineAddr(MCObjectStreamer &OS,
399 : MCDwarfLineTableParams Params,
400 : int64_t LineDelta, const MCSymbol *Label,
401 : int PointerSize) {
402 : // emit the sequence to set the address
403 8072 : OS.EmitIntValue(dwarf::DW_LNS_extended_op, 1);
404 8072 : OS.EmitULEB128IntValue(PointerSize + 1);
405 8072 : OS.EmitIntValue(dwarf::DW_LNE_set_address, 1);
406 8072 : OS.EmitSymbolValue(Label, PointerSize);
407 :
408 : // emit the sequence for the LineDelta (from 1) and a zero address delta.
409 8072 : MCDwarfLineAddr::Emit(&OS, Params, LineDelta, 0);
410 8072 : }
411 :
412 629023 : void MCObjectStreamer::EmitDwarfAdvanceLineAddr(int64_t LineDelta,
413 : const MCSymbol *LastLabel,
414 : const MCSymbol *Label,
415 : unsigned PointerSize) {
416 629023 : if (!LastLabel) {
417 16144 : emitDwarfSetLineAddr(*this, Assembler->getDWARFLinetableParams(), LineDelta,
418 : Label, PointerSize);
419 8412 : return;
420 : }
421 620951 : const MCExpr *AddrDelta = buildSymbolDiff(*this, Label, LastLabel);
422 : int64_t Res;
423 620951 : if (AddrDelta->evaluateAsAbsolute(Res, getAssemblerPtr())) {
424 680 : MCDwarfLineAddr::Emit(this, Assembler->getDWARFLinetableParams(), LineDelta,
425 : Res);
426 340 : return;
427 : }
428 1241222 : insert(new MCDwarfLineAddrFragment(LineDelta, *AddrDelta));
429 : }
430 :
431 940497 : void MCObjectStreamer::EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel,
432 : const MCSymbol *Label) {
433 940497 : const MCExpr *AddrDelta = buildSymbolDiff(*this, Label, LastLabel);
434 : int64_t Res;
435 940497 : if (AddrDelta->evaluateAsAbsolute(Res, getAssemblerPtr())) {
436 348 : MCDwarfFrameEmitter::EmitAdvanceLoc(*this, Res);
437 348 : return;
438 : }
439 940149 : insert(new MCDwarfCallFrameFragment(*AddrDelta));
440 : }
441 :
442 546 : void MCObjectStreamer::EmitCVLocDirective(unsigned FunctionId, unsigned FileNo,
443 : unsigned Line, unsigned Column,
444 : bool PrologueEnd, bool IsStmt,
445 : StringRef FileName, SMLoc Loc) {
446 : // Validate the directive.
447 546 : if (!checkCVLocSection(FunctionId, FileNo, Loc))
448 : return;
449 :
450 : // Emit a label at the current position and record it in the CodeViewContext.
451 546 : MCSymbol *LineSym = getContext().createTempSymbol();
452 546 : EmitLabel(LineSym);
453 546 : getContext().getCVContext().recordCVLoc(getContext(), LineSym, FunctionId,
454 : FileNo, Line, Column, PrologueEnd,
455 : IsStmt);
456 : }
457 :
458 158 : void MCObjectStreamer::EmitCVLinetableDirective(unsigned FunctionId,
459 : const MCSymbol *Begin,
460 : const MCSymbol *End) {
461 158 : getContext().getCVContext().emitLineTableForFunction(*this, FunctionId, Begin,
462 : End);
463 158 : this->MCStreamer::EmitCVLinetableDirective(FunctionId, Begin, End);
464 158 : }
465 :
466 24 : void MCObjectStreamer::EmitCVInlineLinetableDirective(
467 : unsigned PrimaryFunctionId, unsigned SourceFileId, unsigned SourceLineNum,
468 : const MCSymbol *FnStartSym, const MCSymbol *FnEndSym) {
469 24 : getContext().getCVContext().emitInlineLineTableForFunction(
470 : *this, PrimaryFunctionId, SourceFileId, SourceLineNum, FnStartSym,
471 : FnEndSym);
472 24 : this->MCStreamer::EmitCVInlineLinetableDirective(
473 : PrimaryFunctionId, SourceFileId, SourceLineNum, FnStartSym, FnEndSym);
474 24 : }
475 :
476 205 : void MCObjectStreamer::EmitCVDefRangeDirective(
477 : ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
478 : StringRef FixedSizePortion) {
479 205 : getContext().getCVContext().emitDefRange(*this, Ranges, FixedSizePortion);
480 205 : this->MCStreamer::EmitCVDefRangeDirective(Ranges, FixedSizePortion);
481 205 : }
482 :
483 94 : void MCObjectStreamer::EmitCVStringTableDirective() {
484 94 : getContext().getCVContext().emitStringTable(*this);
485 94 : }
486 91 : void MCObjectStreamer::EmitCVFileChecksumsDirective() {
487 91 : getContext().getCVContext().emitFileChecksums(*this);
488 91 : }
489 :
490 182 : void MCObjectStreamer::EmitCVFileChecksumOffsetDirective(unsigned FileNo) {
491 182 : getContext().getCVContext().emitFileChecksumOffset(*this, FileNo);
492 182 : }
493 :
494 11527740 : void MCObjectStreamer::EmitBytes(StringRef Data) {
495 11527740 : MCDwarfLineEntry::Make(this, getCurrentSectionOnly());
496 11527741 : MCDataFragment *DF = getOrCreateDataFragment();
497 23055486 : flushPendingLabels(DF, DF->getContents().size());
498 23055482 : DF->getContents().append(Data.begin(), Data.end());
499 :
500 : // EmitBytes might not cover all possible ways we emit data (or could be used
501 : // to emit executable code in some cases), but is the best method we have
502 : // right now for checking this.
503 : MCSection *Sec = getCurrentSectionOnly();
504 : Sec->setHasData(true);
505 11527741 : }
506 :
507 646094 : void MCObjectStreamer::EmitValueToAlignment(unsigned ByteAlignment,
508 : int64_t Value,
509 : unsigned ValueSize,
510 : unsigned MaxBytesToEmit) {
511 646094 : if (MaxBytesToEmit == 0)
512 : MaxBytesToEmit = ByteAlignment;
513 1292189 : insert(new MCAlignFragment(ByteAlignment, Value, ValueSize, MaxBytesToEmit));
514 :
515 : // Update the maximum alignment on the current section if necessary.
516 : MCSection *CurSec = getCurrentSectionOnly();
517 646095 : if (ByteAlignment > CurSec->getAlignment())
518 : CurSec->setAlignment(ByteAlignment);
519 646095 : }
520 :
521 233157 : void MCObjectStreamer::EmitCodeAlignment(unsigned ByteAlignment,
522 : unsigned MaxBytesToEmit) {
523 233157 : EmitValueToAlignment(ByteAlignment, 0, 1, MaxBytesToEmit);
524 233157 : cast<MCAlignFragment>(getCurrentFragment())->setEmitNops(true);
525 233157 : }
526 :
527 19 : void MCObjectStreamer::emitValueToOffset(const MCExpr *Offset,
528 : unsigned char Value,
529 : SMLoc Loc) {
530 19 : insert(new MCOrgFragment(*Offset, Value, Loc));
531 19 : }
532 :
533 3047534 : void MCObjectStreamer::EmitCodePaddingBasicBlockStart(
534 : const MCCodePaddingContext &Context) {
535 3047534 : getAssembler().getBackend().handleCodePaddingBasicBlockStart(this, Context);
536 3047534 : }
537 :
538 3047534 : void MCObjectStreamer::EmitCodePaddingBasicBlockEnd(
539 : const MCCodePaddingContext &Context) {
540 3047534 : getAssembler().getBackend().handleCodePaddingBasicBlockEnd(Context);
541 3047534 : }
542 :
543 : // Associate DTPRel32 fixup with data and resize data area
544 4 : void MCObjectStreamer::EmitDTPRel32Value(const MCExpr *Value) {
545 4 : MCDataFragment *DF = getOrCreateDataFragment();
546 8 : flushPendingLabels(DF, DF->getContents().size());
547 :
548 8 : DF->getFixups().push_back(MCFixup::create(DF->getContents().size(),
549 : Value, FK_DTPRel_4));
550 8 : DF->getContents().resize(DF->getContents().size() + 4, 0);
551 4 : }
552 :
553 : // Associate DTPRel64 fixup with data and resize data area
554 4 : void MCObjectStreamer::EmitDTPRel64Value(const MCExpr *Value) {
555 4 : MCDataFragment *DF = getOrCreateDataFragment();
556 8 : flushPendingLabels(DF, DF->getContents().size());
557 :
558 8 : DF->getFixups().push_back(MCFixup::create(DF->getContents().size(),
559 : Value, FK_DTPRel_8));
560 8 : DF->getContents().resize(DF->getContents().size() + 8, 0);
561 4 : }
562 :
563 : // Associate TPRel32 fixup with data and resize data area
564 3 : void MCObjectStreamer::EmitTPRel32Value(const MCExpr *Value) {
565 3 : MCDataFragment *DF = getOrCreateDataFragment();
566 6 : flushPendingLabels(DF, DF->getContents().size());
567 :
568 6 : DF->getFixups().push_back(MCFixup::create(DF->getContents().size(),
569 : Value, FK_TPRel_4));
570 6 : DF->getContents().resize(DF->getContents().size() + 4, 0);
571 3 : }
572 :
573 : // Associate TPRel64 fixup with data and resize data area
574 3 : void MCObjectStreamer::EmitTPRel64Value(const MCExpr *Value) {
575 3 : MCDataFragment *DF = getOrCreateDataFragment();
576 6 : flushPendingLabels(DF, DF->getContents().size());
577 :
578 6 : DF->getFixups().push_back(MCFixup::create(DF->getContents().size(),
579 : Value, FK_TPRel_8));
580 6 : DF->getContents().resize(DF->getContents().size() + 8, 0);
581 3 : }
582 :
583 : // Associate GPRel32 fixup with data and resize data area
584 12 : void MCObjectStreamer::EmitGPRel32Value(const MCExpr *Value) {
585 12 : MCDataFragment *DF = getOrCreateDataFragment();
586 24 : flushPendingLabels(DF, DF->getContents().size());
587 :
588 12 : DF->getFixups().push_back(
589 12 : MCFixup::create(DF->getContents().size(), Value, FK_GPRel_4));
590 24 : DF->getContents().resize(DF->getContents().size() + 4, 0);
591 12 : }
592 :
593 : // Associate GPRel64 fixup with data and resize data area
594 13 : void MCObjectStreamer::EmitGPRel64Value(const MCExpr *Value) {
595 13 : MCDataFragment *DF = getOrCreateDataFragment();
596 26 : flushPendingLabels(DF, DF->getContents().size());
597 :
598 13 : DF->getFixups().push_back(
599 13 : MCFixup::create(DF->getContents().size(), Value, FK_GPRel_4));
600 26 : DF->getContents().resize(DF->getContents().size() + 8, 0);
601 13 : }
602 :
603 107 : bool MCObjectStreamer::EmitRelocDirective(const MCExpr &Offset, StringRef Name,
604 : const MCExpr *Expr, SMLoc Loc,
605 : const MCSubtargetInfo &STI) {
606 : int64_t OffsetValue;
607 107 : if (!Offset.evaluateAsAbsolute(OffsetValue))
608 0 : llvm_unreachable("Offset is not absolute");
609 :
610 107 : if (OffsetValue < 0)
611 0 : llvm_unreachable("Offset is negative");
612 :
613 107 : MCDataFragment *DF = getOrCreateDataFragment(&STI);
614 214 : flushPendingLabels(DF, DF->getContents().size());
615 :
616 107 : Optional<MCFixupKind> MaybeKind = Assembler->getBackend().getFixupKind(Name);
617 107 : if (!MaybeKind.hasValue())
618 : return true;
619 :
620 107 : MCFixupKind Kind = *MaybeKind;
621 :
622 107 : if (Expr == nullptr)
623 : Expr =
624 3 : MCSymbolRefExpr::create(getContext().createTempSymbol(), getContext());
625 214 : DF->getFixups().push_back(MCFixup::create(OffsetValue, Expr, Kind, Loc));
626 107 : return false;
627 : }
628 :
629 277914 : void MCObjectStreamer::emitFill(const MCExpr &NumBytes, uint64_t FillValue,
630 : SMLoc Loc) {
631 277914 : MCDataFragment *DF = getOrCreateDataFragment();
632 555828 : flushPendingLabels(DF, DF->getContents().size());
633 :
634 : assert(getCurrentSectionOnly() && "need a section");
635 555828 : insert(new MCFillFragment(FillValue, 1, NumBytes, Loc));
636 277914 : }
637 :
638 546 : void MCObjectStreamer::emitFill(const MCExpr &NumValues, int64_t Size,
639 : int64_t Expr, SMLoc Loc) {
640 : int64_t IntNumValues;
641 : // Do additional checking now if we can resolve the value.
642 546 : if (NumValues.evaluateAsAbsolute(IntNumValues, getAssemblerPtr())) {
643 541 : if (IntNumValues < 0) {
644 4 : getContext().getSourceManager()->PrintMessage(
645 : Loc, SourceMgr::DK_Warning,
646 : "'.fill' directive with negative repeat count has no effect");
647 541 : return;
648 : }
649 : // Emit now if we can for better errors.
650 539 : int64_t NonZeroSize = Size > 4 ? 4 : Size;
651 539 : Expr &= ~0ULL >> (64 - NonZeroSize * 8);
652 1746601 : for (uint64_t i = 0, e = IntNumValues; i != e; ++i) {
653 1746062 : EmitIntValue(Expr, NonZeroSize);
654 1746062 : if (NonZeroSize < Size)
655 7 : EmitIntValue(0, Size - NonZeroSize);
656 : }
657 : return;
658 : }
659 :
660 : // Otherwise emit as fragment.
661 5 : MCDataFragment *DF = getOrCreateDataFragment();
662 10 : flushPendingLabels(DF, DF->getContents().size());
663 :
664 : assert(getCurrentSectionOnly() && "need a section");
665 5 : insert(new MCFillFragment(Expr, Size, NumValues, Loc));
666 : }
667 :
668 7642 : void MCObjectStreamer::EmitFileDirective(StringRef Filename) {
669 7642 : getAssembler().addFileName(Filename);
670 7642 : }
671 :
672 6215 : void MCObjectStreamer::EmitAddrsig() {
673 6215 : getAssembler().getWriter().emitAddrsigSection();
674 6215 : }
675 :
676 237782 : void MCObjectStreamer::EmitAddrsigSym(const MCSymbol *Sym) {
677 237782 : getAssembler().registerSymbol(*Sym);
678 237782 : getAssembler().getWriter().addAddrsigSymbol(Sym);
679 237782 : }
680 :
681 12357 : void MCObjectStreamer::FinishImpl() {
682 12357 : getContext().RemapDebugPaths();
683 :
684 : // If we are generating dwarf for assembly source files dump out the sections.
685 12357 : if (getContext().getGenDwarfForAssembly())
686 33 : MCGenDwarfInfo::Emit(this);
687 :
688 : // Dump out the dwarf file & directory tables and line tables.
689 12357 : MCDwarfLineTable::Emit(this, getAssembler().getDWARFLinetableParams());
690 :
691 : flushPendingLabels();
692 12357 : getAssembler().Finish();
693 12339 : }
|