[lib/ObjectYAML] - Cleanup the private interface of ELFState<ELFT>. NFCI.
[llvm-complete.git] / lib / MC / MCObjectStreamer.cpp
blobb418c2d33d9512273d12aac49183f8b6bfa2653f
1 //===- lib/MC/MCObjectStreamer.cpp - Object File MCStreamer Interface -----===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
9 #include "llvm/MC/MCObjectStreamer.h"
10 #include "llvm/ADT/STLExtras.h"
11 #include "llvm/MC/MCAsmBackend.h"
12 #include "llvm/MC/MCAssembler.h"
13 #include "llvm/MC/MCCodeEmitter.h"
14 #include "llvm/MC/MCCodeView.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/MCSection.h"
20 #include "llvm/MC/MCSymbol.h"
21 #include "llvm/Support/ErrorHandling.h"
22 #include "llvm/Support/SourceMgr.h"
23 using namespace llvm;
25 MCObjectStreamer::MCObjectStreamer(MCContext &Context,
26 std::unique_ptr<MCAsmBackend> TAB,
27 std::unique_ptr<MCObjectWriter> OW,
28 std::unique_ptr<MCCodeEmitter> Emitter)
29 : MCStreamer(Context),
30 Assembler(std::make_unique<MCAssembler>(
31 Context, std::move(TAB), std::move(Emitter), std::move(OW))),
32 EmitEHFrame(true), EmitDebugFrame(false) {}
34 MCObjectStreamer::~MCObjectStreamer() {}
36 // AssemblerPtr is used for evaluation of expressions and causes
37 // difference between asm and object outputs. Return nullptr to in
38 // inline asm mode to limit divergence to assembly inputs.
39 MCAssembler *MCObjectStreamer::getAssemblerPtr() {
40 if (getUseAssemblerInfoForParsing())
41 return Assembler.get();
42 return nullptr;
45 void MCObjectStreamer::flushPendingLabels(MCFragment *F, uint64_t FOffset) {
46 if (PendingLabels.empty())
47 return;
48 if (!F) {
49 F = new MCDataFragment();
50 MCSection *CurSection = getCurrentSectionOnly();
51 CurSection->getFragmentList().insert(CurInsertionPoint, F);
52 F->setParent(CurSection);
54 for (MCSymbol *Sym : PendingLabels) {
55 Sym->setFragment(F);
56 Sym->setOffset(FOffset);
58 PendingLabels.clear();
61 // When fixup's offset is a forward declared label, e.g.:
63 // .reloc 1f, R_MIPS_JALR, foo
64 // 1: nop
66 // postpone adding it to Fixups vector until the label is defined and its offset
67 // is known.
68 void MCObjectStreamer::resolvePendingFixups() {
69 for (PendingMCFixup &PendingFixup : PendingFixups) {
70 if (!PendingFixup.Sym || PendingFixup.Sym->isUndefined ()) {
71 getContext().reportError(PendingFixup.Fixup.getLoc(),
72 "unresolved relocation offset");
73 continue;
75 flushPendingLabels(PendingFixup.DF, PendingFixup.DF->getContents().size());
76 PendingFixup.Fixup.setOffset(PendingFixup.Sym->getOffset());
77 PendingFixup.DF->getFixups().push_back(PendingFixup.Fixup);
79 PendingFixups.clear();
82 // As a compile-time optimization, avoid allocating and evaluating an MCExpr
83 // tree for (Hi - Lo) when Hi and Lo are offsets into the same fragment.
84 static Optional<uint64_t>
85 absoluteSymbolDiff(MCAssembler &Asm, const MCSymbol *Hi, const MCSymbol *Lo) {
86 assert(Hi && Lo);
87 if (Asm.getBackendPtr()->requiresDiffExpressionRelocations())
88 return None;
90 if (!Hi->getFragment() || Hi->getFragment() != Lo->getFragment() ||
91 Hi->isVariable() || Lo->isVariable())
92 return None;
94 return Hi->getOffset() - Lo->getOffset();
97 void MCObjectStreamer::emitAbsoluteSymbolDiff(const MCSymbol *Hi,
98 const MCSymbol *Lo,
99 unsigned Size) {
100 if (Optional<uint64_t> Diff = absoluteSymbolDiff(getAssembler(), Hi, Lo)) {
101 EmitIntValue(*Diff, Size);
102 return;
104 MCStreamer::emitAbsoluteSymbolDiff(Hi, Lo, Size);
107 void MCObjectStreamer::emitAbsoluteSymbolDiffAsULEB128(const MCSymbol *Hi,
108 const MCSymbol *Lo) {
109 if (Optional<uint64_t> Diff = absoluteSymbolDiff(getAssembler(), Hi, Lo)) {
110 EmitULEB128IntValue(*Diff);
111 return;
113 MCStreamer::emitAbsoluteSymbolDiffAsULEB128(Hi, Lo);
116 void MCObjectStreamer::reset() {
117 if (Assembler)
118 Assembler->reset();
119 CurInsertionPoint = MCSection::iterator();
120 EmitEHFrame = true;
121 EmitDebugFrame = false;
122 PendingLabels.clear();
123 MCStreamer::reset();
126 void MCObjectStreamer::EmitFrames(MCAsmBackend *MAB) {
127 if (!getNumFrameInfos())
128 return;
130 if (EmitEHFrame)
131 MCDwarfFrameEmitter::Emit(*this, MAB, true);
133 if (EmitDebugFrame)
134 MCDwarfFrameEmitter::Emit(*this, MAB, false);
137 MCFragment *MCObjectStreamer::getCurrentFragment() const {
138 assert(getCurrentSectionOnly() && "No current section!");
140 if (CurInsertionPoint != getCurrentSectionOnly()->getFragmentList().begin())
141 return &*std::prev(CurInsertionPoint);
143 return nullptr;
146 static bool CanReuseDataFragment(const MCDataFragment &F,
147 const MCAssembler &Assembler,
148 const MCSubtargetInfo *STI) {
149 if (!F.hasInstructions())
150 return true;
151 // When bundling is enabled, we don't want to add data to a fragment that
152 // already has instructions (see MCELFStreamer::EmitInstToData for details)
153 if (Assembler.isBundlingEnabled())
154 return Assembler.getRelaxAll();
155 // If the subtarget is changed mid fragment we start a new fragment to record
156 // the new STI.
157 return !STI || F.getSubtargetInfo() == STI;
160 MCDataFragment *
161 MCObjectStreamer::getOrCreateDataFragment(const MCSubtargetInfo *STI) {
162 MCDataFragment *F = dyn_cast_or_null<MCDataFragment>(getCurrentFragment());
163 if (!F || !CanReuseDataFragment(*F, *Assembler, STI)) {
164 F = new MCDataFragment();
165 insert(F);
167 return F;
170 MCPaddingFragment *MCObjectStreamer::getOrCreatePaddingFragment() {
171 MCPaddingFragment *F =
172 dyn_cast_or_null<MCPaddingFragment>(getCurrentFragment());
173 if (!F) {
174 F = new MCPaddingFragment();
175 insert(F);
177 return F;
180 void MCObjectStreamer::visitUsedSymbol(const MCSymbol &Sym) {
181 Assembler->registerSymbol(Sym);
184 void MCObjectStreamer::EmitCFISections(bool EH, bool Debug) {
185 MCStreamer::EmitCFISections(EH, Debug);
186 EmitEHFrame = EH;
187 EmitDebugFrame = Debug;
190 void MCObjectStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size,
191 SMLoc Loc) {
192 MCStreamer::EmitValueImpl(Value, Size, Loc);
193 MCDataFragment *DF = getOrCreateDataFragment();
194 flushPendingLabels(DF, DF->getContents().size());
196 MCDwarfLineEntry::Make(this, getCurrentSectionOnly());
198 // Avoid fixups when possible.
199 int64_t AbsValue;
200 if (Value->evaluateAsAbsolute(AbsValue, getAssemblerPtr())) {
201 if (!isUIntN(8 * Size, AbsValue) && !isIntN(8 * Size, AbsValue)) {
202 getContext().reportError(
203 Loc, "value evaluated as " + Twine(AbsValue) + " is out of range.");
204 return;
206 EmitIntValue(AbsValue, Size);
207 return;
209 DF->getFixups().push_back(
210 MCFixup::create(DF->getContents().size(), Value,
211 MCFixup::getKindForSize(Size, false), Loc));
212 DF->getContents().resize(DF->getContents().size() + Size, 0);
215 MCSymbol *MCObjectStreamer::EmitCFILabel() {
216 MCSymbol *Label = getContext().createTempSymbol("cfi", true);
217 EmitLabel(Label);
218 return Label;
221 void MCObjectStreamer::EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) {
222 // We need to create a local symbol to avoid relocations.
223 Frame.Begin = getContext().createTempSymbol();
224 EmitLabel(Frame.Begin);
227 void MCObjectStreamer::EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) {
228 Frame.End = getContext().createTempSymbol();
229 EmitLabel(Frame.End);
232 void MCObjectStreamer::EmitLabel(MCSymbol *Symbol, SMLoc Loc) {
233 MCStreamer::EmitLabel(Symbol, Loc);
235 getAssembler().registerSymbol(*Symbol);
237 // If there is a current fragment, mark the symbol as pointing into it.
238 // Otherwise queue the label and set its fragment pointer when we emit the
239 // next fragment.
240 auto *F = dyn_cast_or_null<MCDataFragment>(getCurrentFragment());
241 if (F && !(getAssembler().isBundlingEnabled() &&
242 getAssembler().getRelaxAll())) {
243 Symbol->setFragment(F);
244 Symbol->setOffset(F->getContents().size());
245 } else {
246 PendingLabels.push_back(Symbol);
250 void MCObjectStreamer::EmitLabel(MCSymbol *Symbol, SMLoc Loc, MCFragment *F) {
251 MCStreamer::EmitLabel(Symbol, Loc);
252 getAssembler().registerSymbol(*Symbol);
253 auto *DF = dyn_cast_or_null<MCDataFragment>(F);
254 if (DF)
255 Symbol->setFragment(F);
256 else
257 PendingLabels.push_back(Symbol);
260 void MCObjectStreamer::EmitULEB128Value(const MCExpr *Value) {
261 int64_t IntValue;
262 if (Value->evaluateAsAbsolute(IntValue, getAssemblerPtr())) {
263 EmitULEB128IntValue(IntValue);
264 return;
266 insert(new MCLEBFragment(*Value, false));
269 void MCObjectStreamer::EmitSLEB128Value(const MCExpr *Value) {
270 int64_t IntValue;
271 if (Value->evaluateAsAbsolute(IntValue, getAssemblerPtr())) {
272 EmitSLEB128IntValue(IntValue);
273 return;
275 insert(new MCLEBFragment(*Value, true));
278 void MCObjectStreamer::EmitWeakReference(MCSymbol *Alias,
279 const MCSymbol *Symbol) {
280 report_fatal_error("This file format doesn't support weak aliases.");
283 void MCObjectStreamer::ChangeSection(MCSection *Section,
284 const MCExpr *Subsection) {
285 changeSectionImpl(Section, Subsection);
288 bool MCObjectStreamer::changeSectionImpl(MCSection *Section,
289 const MCExpr *Subsection) {
290 assert(Section && "Cannot switch to a null section!");
291 flushPendingLabels(nullptr);
292 getContext().clearDwarfLocSeen();
294 bool Created = getAssembler().registerSection(*Section);
296 int64_t IntSubsection = 0;
297 if (Subsection &&
298 !Subsection->evaluateAsAbsolute(IntSubsection, getAssemblerPtr()))
299 report_fatal_error("Cannot evaluate subsection number");
300 if (IntSubsection < 0 || IntSubsection > 8192)
301 report_fatal_error("Subsection number out of range");
302 CurInsertionPoint =
303 Section->getSubsectionInsertionPoint(unsigned(IntSubsection));
304 return Created;
307 void MCObjectStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) {
308 getAssembler().registerSymbol(*Symbol);
309 MCStreamer::EmitAssignment(Symbol, Value);
312 bool MCObjectStreamer::mayHaveInstructions(MCSection &Sec) const {
313 return Sec.hasInstructions();
316 void MCObjectStreamer::EmitInstruction(const MCInst &Inst,
317 const MCSubtargetInfo &STI) {
318 getAssembler().getBackend().handleCodePaddingInstructionBegin(Inst);
319 EmitInstructionImpl(Inst, STI);
320 getAssembler().getBackend().handleCodePaddingInstructionEnd(Inst);
323 void MCObjectStreamer::EmitInstructionImpl(const MCInst &Inst,
324 const MCSubtargetInfo &STI) {
325 MCStreamer::EmitInstruction(Inst, STI);
327 MCSection *Sec = getCurrentSectionOnly();
328 Sec->setHasInstructions(true);
330 // Now that a machine instruction has been assembled into this section, make
331 // a line entry for any .loc directive that has been seen.
332 MCDwarfLineEntry::Make(this, getCurrentSectionOnly());
334 // If this instruction doesn't need relaxation, just emit it as data.
335 MCAssembler &Assembler = getAssembler();
336 if (!Assembler.getBackend().mayNeedRelaxation(Inst, STI)) {
337 EmitInstToData(Inst, STI);
338 return;
341 // Otherwise, relax and emit it as data if either:
342 // - The RelaxAll flag was passed
343 // - Bundling is enabled and this instruction is inside a bundle-locked
344 // group. We want to emit all such instructions into the same data
345 // fragment.
346 if (Assembler.getRelaxAll() ||
347 (Assembler.isBundlingEnabled() && Sec->isBundleLocked())) {
348 MCInst Relaxed;
349 getAssembler().getBackend().relaxInstruction(Inst, STI, Relaxed);
350 while (getAssembler().getBackend().mayNeedRelaxation(Relaxed, STI))
351 getAssembler().getBackend().relaxInstruction(Relaxed, STI, Relaxed);
352 EmitInstToData(Relaxed, STI);
353 return;
356 // Otherwise emit to a separate fragment.
357 EmitInstToFragment(Inst, STI);
360 void MCObjectStreamer::EmitInstToFragment(const MCInst &Inst,
361 const MCSubtargetInfo &STI) {
362 if (getAssembler().getRelaxAll() && getAssembler().isBundlingEnabled())
363 llvm_unreachable("All instructions should have already been relaxed");
365 // Always create a new, separate fragment here, because its size can change
366 // during relaxation.
367 MCRelaxableFragment *IF = new MCRelaxableFragment(Inst, STI);
368 insert(IF);
370 SmallString<128> Code;
371 raw_svector_ostream VecOS(Code);
372 getAssembler().getEmitter().encodeInstruction(Inst, VecOS, IF->getFixups(),
373 STI);
374 IF->getContents().append(Code.begin(), Code.end());
377 #ifndef NDEBUG
378 static const char *const BundlingNotImplementedMsg =
379 "Aligned bundling is not implemented for this object format";
380 #endif
382 void MCObjectStreamer::EmitBundleAlignMode(unsigned AlignPow2) {
383 llvm_unreachable(BundlingNotImplementedMsg);
386 void MCObjectStreamer::EmitBundleLock(bool AlignToEnd) {
387 llvm_unreachable(BundlingNotImplementedMsg);
390 void MCObjectStreamer::EmitBundleUnlock() {
391 llvm_unreachable(BundlingNotImplementedMsg);
394 void MCObjectStreamer::EmitDwarfLocDirective(unsigned FileNo, unsigned Line,
395 unsigned Column, unsigned Flags,
396 unsigned Isa,
397 unsigned Discriminator,
398 StringRef FileName) {
399 // In case we see two .loc directives in a row, make sure the
400 // first one gets a line entry.
401 MCDwarfLineEntry::Make(this, getCurrentSectionOnly());
403 this->MCStreamer::EmitDwarfLocDirective(FileNo, Line, Column, Flags,
404 Isa, Discriminator, FileName);
407 static const MCExpr *buildSymbolDiff(MCObjectStreamer &OS, const MCSymbol *A,
408 const MCSymbol *B) {
409 MCContext &Context = OS.getContext();
410 MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
411 const MCExpr *ARef = MCSymbolRefExpr::create(A, Variant, Context);
412 const MCExpr *BRef = MCSymbolRefExpr::create(B, Variant, Context);
413 const MCExpr *AddrDelta =
414 MCBinaryExpr::create(MCBinaryExpr::Sub, ARef, BRef, Context);
415 return AddrDelta;
418 static void emitDwarfSetLineAddr(MCObjectStreamer &OS,
419 MCDwarfLineTableParams Params,
420 int64_t LineDelta, const MCSymbol *Label,
421 int PointerSize) {
422 // emit the sequence to set the address
423 OS.EmitIntValue(dwarf::DW_LNS_extended_op, 1);
424 OS.EmitULEB128IntValue(PointerSize + 1);
425 OS.EmitIntValue(dwarf::DW_LNE_set_address, 1);
426 OS.EmitSymbolValue(Label, PointerSize);
428 // emit the sequence for the LineDelta (from 1) and a zero address delta.
429 MCDwarfLineAddr::Emit(&OS, Params, LineDelta, 0);
432 void MCObjectStreamer::EmitDwarfAdvanceLineAddr(int64_t LineDelta,
433 const MCSymbol *LastLabel,
434 const MCSymbol *Label,
435 unsigned PointerSize) {
436 if (!LastLabel) {
437 emitDwarfSetLineAddr(*this, Assembler->getDWARFLinetableParams(), LineDelta,
438 Label, PointerSize);
439 return;
441 const MCExpr *AddrDelta = buildSymbolDiff(*this, Label, LastLabel);
442 int64_t Res;
443 if (AddrDelta->evaluateAsAbsolute(Res, getAssemblerPtr())) {
444 MCDwarfLineAddr::Emit(this, Assembler->getDWARFLinetableParams(), LineDelta,
445 Res);
446 return;
448 insert(new MCDwarfLineAddrFragment(LineDelta, *AddrDelta));
451 void MCObjectStreamer::EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel,
452 const MCSymbol *Label) {
453 const MCExpr *AddrDelta = buildSymbolDiff(*this, Label, LastLabel);
454 int64_t Res;
455 if (AddrDelta->evaluateAsAbsolute(Res, getAssemblerPtr())) {
456 MCDwarfFrameEmitter::EmitAdvanceLoc(*this, Res);
457 return;
459 insert(new MCDwarfCallFrameFragment(*AddrDelta));
462 void MCObjectStreamer::EmitCVLocDirective(unsigned FunctionId, unsigned FileNo,
463 unsigned Line, unsigned Column,
464 bool PrologueEnd, bool IsStmt,
465 StringRef FileName, SMLoc Loc) {
466 // Validate the directive.
467 if (!checkCVLocSection(FunctionId, FileNo, Loc))
468 return;
470 // Emit a label at the current position and record it in the CodeViewContext.
471 MCSymbol *LineSym = getContext().createTempSymbol();
472 EmitLabel(LineSym);
473 getContext().getCVContext().recordCVLoc(getContext(), LineSym, FunctionId,
474 FileNo, Line, Column, PrologueEnd,
475 IsStmt);
478 void MCObjectStreamer::EmitCVLinetableDirective(unsigned FunctionId,
479 const MCSymbol *Begin,
480 const MCSymbol *End) {
481 getContext().getCVContext().emitLineTableForFunction(*this, FunctionId, Begin,
482 End);
483 this->MCStreamer::EmitCVLinetableDirective(FunctionId, Begin, End);
486 void MCObjectStreamer::EmitCVInlineLinetableDirective(
487 unsigned PrimaryFunctionId, unsigned SourceFileId, unsigned SourceLineNum,
488 const MCSymbol *FnStartSym, const MCSymbol *FnEndSym) {
489 getContext().getCVContext().emitInlineLineTableForFunction(
490 *this, PrimaryFunctionId, SourceFileId, SourceLineNum, FnStartSym,
491 FnEndSym);
492 this->MCStreamer::EmitCVInlineLinetableDirective(
493 PrimaryFunctionId, SourceFileId, SourceLineNum, FnStartSym, FnEndSym);
496 void MCObjectStreamer::EmitCVDefRangeDirective(
497 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
498 StringRef FixedSizePortion) {
499 MCFragment *Frag =
500 getContext().getCVContext().emitDefRange(*this, Ranges, FixedSizePortion);
501 // Attach labels that were pending before we created the defrange fragment to
502 // the beginning of the new fragment.
503 flushPendingLabels(Frag, 0);
504 this->MCStreamer::EmitCVDefRangeDirective(Ranges, FixedSizePortion);
507 void MCObjectStreamer::EmitCVStringTableDirective() {
508 getContext().getCVContext().emitStringTable(*this);
510 void MCObjectStreamer::EmitCVFileChecksumsDirective() {
511 getContext().getCVContext().emitFileChecksums(*this);
514 void MCObjectStreamer::EmitCVFileChecksumOffsetDirective(unsigned FileNo) {
515 getContext().getCVContext().emitFileChecksumOffset(*this, FileNo);
518 void MCObjectStreamer::EmitBytes(StringRef Data) {
519 MCDwarfLineEntry::Make(this, getCurrentSectionOnly());
520 MCDataFragment *DF = getOrCreateDataFragment();
521 flushPendingLabels(DF, DF->getContents().size());
522 DF->getContents().append(Data.begin(), Data.end());
524 // EmitBytes might not cover all possible ways we emit data (or could be used
525 // to emit executable code in some cases), but is the best method we have
526 // right now for checking this.
527 MCSection *Sec = getCurrentSectionOnly();
528 Sec->setHasData(true);
531 void MCObjectStreamer::EmitValueToAlignment(unsigned ByteAlignment,
532 int64_t Value,
533 unsigned ValueSize,
534 unsigned MaxBytesToEmit) {
535 if (MaxBytesToEmit == 0)
536 MaxBytesToEmit = ByteAlignment;
537 insert(new MCAlignFragment(ByteAlignment, Value, ValueSize, MaxBytesToEmit));
539 // Update the maximum alignment on the current section if necessary.
540 MCSection *CurSec = getCurrentSectionOnly();
541 if (ByteAlignment > CurSec->getAlignment())
542 CurSec->setAlignment(ByteAlignment);
545 void MCObjectStreamer::EmitCodeAlignment(unsigned ByteAlignment,
546 unsigned MaxBytesToEmit) {
547 EmitValueToAlignment(ByteAlignment, 0, 1, MaxBytesToEmit);
548 cast<MCAlignFragment>(getCurrentFragment())->setEmitNops(true);
551 void MCObjectStreamer::emitValueToOffset(const MCExpr *Offset,
552 unsigned char Value,
553 SMLoc Loc) {
554 insert(new MCOrgFragment(*Offset, Value, Loc));
557 void MCObjectStreamer::EmitCodePaddingBasicBlockStart(
558 const MCCodePaddingContext &Context) {
559 getAssembler().getBackend().handleCodePaddingBasicBlockStart(this, Context);
562 void MCObjectStreamer::EmitCodePaddingBasicBlockEnd(
563 const MCCodePaddingContext &Context) {
564 getAssembler().getBackend().handleCodePaddingBasicBlockEnd(Context);
567 // Associate DTPRel32 fixup with data and resize data area
568 void MCObjectStreamer::EmitDTPRel32Value(const MCExpr *Value) {
569 MCDataFragment *DF = getOrCreateDataFragment();
570 flushPendingLabels(DF, DF->getContents().size());
572 DF->getFixups().push_back(MCFixup::create(DF->getContents().size(),
573 Value, FK_DTPRel_4));
574 DF->getContents().resize(DF->getContents().size() + 4, 0);
577 // Associate DTPRel64 fixup with data and resize data area
578 void MCObjectStreamer::EmitDTPRel64Value(const MCExpr *Value) {
579 MCDataFragment *DF = getOrCreateDataFragment();
580 flushPendingLabels(DF, DF->getContents().size());
582 DF->getFixups().push_back(MCFixup::create(DF->getContents().size(),
583 Value, FK_DTPRel_8));
584 DF->getContents().resize(DF->getContents().size() + 8, 0);
587 // Associate TPRel32 fixup with data and resize data area
588 void MCObjectStreamer::EmitTPRel32Value(const MCExpr *Value) {
589 MCDataFragment *DF = getOrCreateDataFragment();
590 flushPendingLabels(DF, DF->getContents().size());
592 DF->getFixups().push_back(MCFixup::create(DF->getContents().size(),
593 Value, FK_TPRel_4));
594 DF->getContents().resize(DF->getContents().size() + 4, 0);
597 // Associate TPRel64 fixup with data and resize data area
598 void MCObjectStreamer::EmitTPRel64Value(const MCExpr *Value) {
599 MCDataFragment *DF = getOrCreateDataFragment();
600 flushPendingLabels(DF, DF->getContents().size());
602 DF->getFixups().push_back(MCFixup::create(DF->getContents().size(),
603 Value, FK_TPRel_8));
604 DF->getContents().resize(DF->getContents().size() + 8, 0);
607 // Associate GPRel32 fixup with data and resize data area
608 void MCObjectStreamer::EmitGPRel32Value(const MCExpr *Value) {
609 MCDataFragment *DF = getOrCreateDataFragment();
610 flushPendingLabels(DF, DF->getContents().size());
612 DF->getFixups().push_back(
613 MCFixup::create(DF->getContents().size(), Value, FK_GPRel_4));
614 DF->getContents().resize(DF->getContents().size() + 4, 0);
617 // Associate GPRel64 fixup with data and resize data area
618 void MCObjectStreamer::EmitGPRel64Value(const MCExpr *Value) {
619 MCDataFragment *DF = getOrCreateDataFragment();
620 flushPendingLabels(DF, DF->getContents().size());
622 DF->getFixups().push_back(
623 MCFixup::create(DF->getContents().size(), Value, FK_GPRel_4));
624 DF->getContents().resize(DF->getContents().size() + 8, 0);
627 bool MCObjectStreamer::EmitRelocDirective(const MCExpr &Offset, StringRef Name,
628 const MCExpr *Expr, SMLoc Loc,
629 const MCSubtargetInfo &STI) {
630 Optional<MCFixupKind> MaybeKind = Assembler->getBackend().getFixupKind(Name);
631 if (!MaybeKind.hasValue())
632 return true;
634 MCFixupKind Kind = *MaybeKind;
636 if (Expr == nullptr)
637 Expr =
638 MCSymbolRefExpr::create(getContext().createTempSymbol(), getContext());
640 MCDataFragment *DF = getOrCreateDataFragment(&STI);
641 flushPendingLabels(DF, DF->getContents().size());
643 int64_t OffsetValue;
644 if (Offset.evaluateAsAbsolute(OffsetValue)) {
645 if (OffsetValue < 0)
646 llvm_unreachable(".reloc offset is negative");
647 DF->getFixups().push_back(MCFixup::create(OffsetValue, Expr, Kind, Loc));
648 return false;
651 if (Offset.getKind() != llvm::MCExpr::SymbolRef)
652 llvm_unreachable(".reloc offset is not absolute nor a label");
654 const MCSymbolRefExpr &SRE = cast<MCSymbolRefExpr>(Offset);
655 if (SRE.getSymbol().isDefined()) {
656 DF->getFixups().push_back(MCFixup::create(SRE.getSymbol().getOffset(),
657 Expr, Kind, Loc));
658 return false;
661 PendingFixups.emplace_back(&SRE.getSymbol(), DF,
662 MCFixup::create(-1, Expr, Kind, Loc));
663 return false;
666 void MCObjectStreamer::emitFill(const MCExpr &NumBytes, uint64_t FillValue,
667 SMLoc Loc) {
668 MCDataFragment *DF = getOrCreateDataFragment();
669 flushPendingLabels(DF, DF->getContents().size());
671 assert(getCurrentSectionOnly() && "need a section");
672 insert(new MCFillFragment(FillValue, 1, NumBytes, Loc));
675 void MCObjectStreamer::emitFill(const MCExpr &NumValues, int64_t Size,
676 int64_t Expr, SMLoc Loc) {
677 int64_t IntNumValues;
678 // Do additional checking now if we can resolve the value.
679 if (NumValues.evaluateAsAbsolute(IntNumValues, getAssemblerPtr())) {
680 if (IntNumValues < 0) {
681 getContext().getSourceManager()->PrintMessage(
682 Loc, SourceMgr::DK_Warning,
683 "'.fill' directive with negative repeat count has no effect");
684 return;
686 // Emit now if we can for better errors.
687 int64_t NonZeroSize = Size > 4 ? 4 : Size;
688 Expr &= ~0ULL >> (64 - NonZeroSize * 8);
689 for (uint64_t i = 0, e = IntNumValues; i != e; ++i) {
690 EmitIntValue(Expr, NonZeroSize);
691 if (NonZeroSize < Size)
692 EmitIntValue(0, Size - NonZeroSize);
694 return;
697 // Otherwise emit as fragment.
698 MCDataFragment *DF = getOrCreateDataFragment();
699 flushPendingLabels(DF, DF->getContents().size());
701 assert(getCurrentSectionOnly() && "need a section");
702 insert(new MCFillFragment(Expr, Size, NumValues, Loc));
705 void MCObjectStreamer::EmitFileDirective(StringRef Filename) {
706 getAssembler().addFileName(Filename);
709 void MCObjectStreamer::EmitAddrsig() {
710 getAssembler().getWriter().emitAddrsigSection();
713 void MCObjectStreamer::EmitAddrsigSym(const MCSymbol *Sym) {
714 getAssembler().registerSymbol(*Sym);
715 getAssembler().getWriter().addAddrsigSymbol(Sym);
718 void MCObjectStreamer::FinishImpl() {
719 getContext().RemapDebugPaths();
721 // If we are generating dwarf for assembly source files dump out the sections.
722 if (getContext().getGenDwarfForAssembly())
723 MCGenDwarfInfo::Emit(this);
725 // Dump out the dwarf file & directory tables and line tables.
726 MCDwarfLineTable::Emit(this, getAssembler().getDWARFLinetableParams());
728 flushPendingLabels();
729 resolvePendingFixups();
730 getAssembler().Finish();