[ELF] Avoid make in elf::writeARMCmseImportLib
[llvm-project.git] / llvm / lib / MC / MCObjectStreamer.cpp
blobb2b21435fa4af4a8ad7b5ea6db50a9139d8c1abf
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/MC/MCAsmBackend.h"
11 #include "llvm/MC/MCAsmInfo.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/MCObjectFileInfo.h"
19 #include "llvm/MC/MCObjectWriter.h"
20 #include "llvm/MC/MCSection.h"
21 #include "llvm/MC/MCSymbol.h"
22 #include "llvm/MC/MCValue.h"
23 #include "llvm/Support/ErrorHandling.h"
24 #include "llvm/Support/SourceMgr.h"
25 using namespace llvm;
27 MCObjectStreamer::MCObjectStreamer(MCContext &Context,
28 std::unique_ptr<MCAsmBackend> TAB,
29 std::unique_ptr<MCObjectWriter> OW,
30 std::unique_ptr<MCCodeEmitter> Emitter)
31 : MCStreamer(Context),
32 Assembler(std::make_unique<MCAssembler>(
33 Context, std::move(TAB), std::move(Emitter), std::move(OW))),
34 EmitEHFrame(true), EmitDebugFrame(false) {
35 assert(Assembler->getBackendPtr() && Assembler->getEmitterPtr());
36 setAllowAutoPadding(Assembler->getBackend().allowAutoPadding());
37 if (Context.getTargetOptions() && Context.getTargetOptions()->MCRelaxAll)
38 Assembler->setRelaxAll(true);
41 MCObjectStreamer::~MCObjectStreamer() = default;
43 MCAssembler *MCObjectStreamer::getAssemblerPtr() {
44 if (getUseAssemblerInfoForParsing())
45 return Assembler.get();
46 return nullptr;
49 // When fixup's offset is a forward declared label, e.g.:
51 // .reloc 1f, R_MIPS_JALR, foo
52 // 1: nop
54 // postpone adding it to Fixups vector until the label is defined and its offset
55 // is known.
56 void MCObjectStreamer::resolvePendingFixups() {
57 for (PendingMCFixup &PendingFixup : PendingFixups) {
58 if (!PendingFixup.Sym || PendingFixup.Sym->isUndefined ()) {
59 getContext().reportError(PendingFixup.Fixup.getLoc(),
60 "unresolved relocation offset");
61 continue;
63 PendingFixup.Fixup.setOffset(PendingFixup.Sym->getOffset() +
64 PendingFixup.Fixup.getOffset());
66 // If the location symbol to relocate is in MCEncodedFragmentWithFixups,
67 // put the Fixup into location symbol's fragment. Otherwise
68 // put into PendingFixup.DF
69 MCFragment *SymFragment = PendingFixup.Sym->getFragment();
70 switch (SymFragment->getKind()) {
71 case MCFragment::FT_Relaxable:
72 case MCFragment::FT_Dwarf:
73 case MCFragment::FT_PseudoProbe:
74 cast<MCEncodedFragmentWithFixups<8, 1>>(SymFragment)
75 ->getFixups()
76 .push_back(PendingFixup.Fixup);
77 break;
78 case MCFragment::FT_Data:
79 case MCFragment::FT_CVDefRange:
80 cast<MCEncodedFragmentWithFixups<32, 4>>(SymFragment)
81 ->getFixups()
82 .push_back(PendingFixup.Fixup);
83 break;
84 default:
85 PendingFixup.DF->getFixups().push_back(PendingFixup.Fixup);
86 break;
89 PendingFixups.clear();
92 // As a compile-time optimization, avoid allocating and evaluating an MCExpr
93 // tree for (Hi - Lo) when Hi and Lo are offsets into the same fragment.
94 static std::optional<uint64_t> absoluteSymbolDiff(const MCSymbol *Hi,
95 const MCSymbol *Lo) {
96 assert(Hi && Lo);
97 if (!Hi->getFragment() || Hi->getFragment() != Lo->getFragment() ||
98 Hi->isVariable() || Lo->isVariable())
99 return std::nullopt;
101 return Hi->getOffset() - Lo->getOffset();
104 void MCObjectStreamer::emitAbsoluteSymbolDiff(const MCSymbol *Hi,
105 const MCSymbol *Lo,
106 unsigned Size) {
107 if (!getAssembler().getContext().getTargetTriple().isRISCV())
108 if (std::optional<uint64_t> Diff = absoluteSymbolDiff(Hi, Lo))
109 return emitIntValue(*Diff, Size);
110 MCStreamer::emitAbsoluteSymbolDiff(Hi, Lo, Size);
113 void MCObjectStreamer::emitAbsoluteSymbolDiffAsULEB128(const MCSymbol *Hi,
114 const MCSymbol *Lo) {
115 if (!getAssembler().getContext().getTargetTriple().isRISCV())
116 if (std::optional<uint64_t> Diff = absoluteSymbolDiff(Hi, Lo)) {
117 emitULEB128IntValue(*Diff);
118 return;
120 MCStreamer::emitAbsoluteSymbolDiffAsULEB128(Hi, Lo);
123 void MCObjectStreamer::reset() {
124 if (Assembler) {
125 Assembler->reset();
126 if (getContext().getTargetOptions())
127 Assembler->setRelaxAll(getContext().getTargetOptions()->MCRelaxAll);
129 EmitEHFrame = true;
130 EmitDebugFrame = false;
131 MCStreamer::reset();
134 void MCObjectStreamer::emitFrames(MCAsmBackend *MAB) {
135 if (!getNumFrameInfos())
136 return;
138 if (EmitEHFrame)
139 MCDwarfFrameEmitter::Emit(*this, MAB, true);
141 if (EmitDebugFrame)
142 MCDwarfFrameEmitter::Emit(*this, MAB, false);
145 static bool canReuseDataFragment(const MCDataFragment &F,
146 const MCAssembler &Assembler,
147 const MCSubtargetInfo *STI) {
148 if (!F.hasInstructions())
149 return true;
150 // Do not add data after a linker-relaxable instruction. The difference
151 // between a new label and a label at or before the linker-relaxable
152 // instruction cannot be resolved at assemble-time.
153 if (F.isLinkerRelaxable())
154 return false;
155 // When bundling is enabled, we don't want to add data to a fragment that
156 // already has instructions (see MCELFStreamer::emitInstToData for details)
157 if (Assembler.isBundlingEnabled())
158 return false;
159 // If the subtarget is changed mid fragment we start a new fragment to record
160 // the new STI.
161 return !STI || F.getSubtargetInfo() == STI;
164 MCDataFragment *
165 MCObjectStreamer::getOrCreateDataFragment(const MCSubtargetInfo *STI) {
166 auto *F = dyn_cast<MCDataFragment>(getCurrentFragment());
167 if (!F || !canReuseDataFragment(*F, *Assembler, STI)) {
168 F = getContext().allocFragment<MCDataFragment>();
169 insert(F);
171 return F;
174 void MCObjectStreamer::visitUsedSymbol(const MCSymbol &Sym) {
175 Assembler->registerSymbol(Sym);
178 void MCObjectStreamer::emitCFISections(bool EH, bool Debug) {
179 MCStreamer::emitCFISections(EH, Debug);
180 EmitEHFrame = EH;
181 EmitDebugFrame = Debug;
184 void MCObjectStreamer::emitValueImpl(const MCExpr *Value, unsigned Size,
185 SMLoc Loc) {
186 MCStreamer::emitValueImpl(Value, Size, Loc);
187 MCDataFragment *DF = getOrCreateDataFragment();
189 MCDwarfLineEntry::make(this, getCurrentSectionOnly());
191 // Avoid fixups when possible.
192 int64_t AbsValue;
193 if (Value->evaluateAsAbsolute(AbsValue, getAssemblerPtr())) {
194 if (!isUIntN(8 * Size, AbsValue) && !isIntN(8 * Size, AbsValue)) {
195 getContext().reportError(
196 Loc, "value evaluated as " + Twine(AbsValue) + " is out of range.");
197 return;
199 emitIntValue(AbsValue, Size);
200 return;
202 DF->getFixups().push_back(
203 MCFixup::create(DF->getContents().size(), Value,
204 MCFixup::getKindForSize(Size, false), Loc));
205 DF->getContents().resize(DF->getContents().size() + Size, 0);
208 MCSymbol *MCObjectStreamer::emitCFILabel() {
209 MCSymbol *Label = getContext().createTempSymbol("cfi");
210 emitLabel(Label);
211 return Label;
214 void MCObjectStreamer::emitCFIStartProcImpl(MCDwarfFrameInfo &Frame) {
215 // We need to create a local symbol to avoid relocations.
216 Frame.Begin = getContext().createTempSymbol();
217 emitLabel(Frame.Begin);
220 void MCObjectStreamer::emitCFIEndProcImpl(MCDwarfFrameInfo &Frame) {
221 Frame.End = getContext().createTempSymbol();
222 emitLabel(Frame.End);
225 void MCObjectStreamer::emitLabel(MCSymbol *Symbol, SMLoc Loc) {
226 MCStreamer::emitLabel(Symbol, Loc);
228 getAssembler().registerSymbol(*Symbol);
230 // If there is a current fragment, mark the symbol as pointing into it.
231 // Otherwise queue the label and set its fragment pointer when we emit the
232 // next fragment.
233 MCDataFragment *F = getOrCreateDataFragment();
234 Symbol->setFragment(F);
235 Symbol->setOffset(F->getContents().size());
237 emitPendingAssignments(Symbol);
240 void MCObjectStreamer::emitPendingAssignments(MCSymbol *Symbol) {
241 auto Assignments = pendingAssignments.find(Symbol);
242 if (Assignments != pendingAssignments.end()) {
243 for (const PendingAssignment &A : Assignments->second)
244 emitAssignment(A.Symbol, A.Value);
246 pendingAssignments.erase(Assignments);
250 // Emit a label at a previously emitted fragment/offset position. This must be
251 // within the currently-active section.
252 void MCObjectStreamer::emitLabelAtPos(MCSymbol *Symbol, SMLoc Loc,
253 MCDataFragment &F, uint64_t Offset) {
254 assert(F.getParent() == getCurrentSectionOnly());
255 MCStreamer::emitLabel(Symbol, Loc);
256 getAssembler().registerSymbol(*Symbol);
257 Symbol->setFragment(&F);
258 Symbol->setOffset(Offset);
261 void MCObjectStreamer::emitULEB128Value(const MCExpr *Value) {
262 int64_t IntValue;
263 if (Value->evaluateAsAbsolute(IntValue, getAssemblerPtr())) {
264 emitULEB128IntValue(IntValue);
265 return;
267 insert(getContext().allocFragment<MCLEBFragment>(*Value, false));
270 void MCObjectStreamer::emitSLEB128Value(const MCExpr *Value) {
271 int64_t IntValue;
272 if (Value->evaluateAsAbsolute(IntValue, getAssemblerPtr())) {
273 emitSLEB128IntValue(IntValue);
274 return;
276 insert(getContext().allocFragment<MCLEBFragment>(*Value, true));
279 void MCObjectStreamer::emitWeakReference(MCSymbol *Alias,
280 const MCSymbol *Symbol) {
281 report_fatal_error("This file format doesn't support weak aliases.");
284 void MCObjectStreamer::changeSection(MCSection *Section, uint32_t Subsection) {
285 changeSectionImpl(Section, Subsection);
288 bool MCObjectStreamer::changeSectionImpl(MCSection *Section,
289 uint32_t Subsection) {
290 assert(Section && "Cannot switch to a null section!");
291 getContext().clearDwarfLocSeen();
293 auto &Subsections = Section->Subsections;
294 size_t I = 0, E = Subsections.size();
295 while (I != E && Subsections[I].first < Subsection)
296 ++I;
297 // If the subsection number is not in the sorted Subsections list, create a
298 // new fragment list.
299 if (I == E || Subsections[I].first != Subsection) {
300 auto *F = getContext().allocFragment<MCDataFragment>();
301 F->setParent(Section);
302 Subsections.insert(Subsections.begin() + I,
303 {Subsection, MCSection::FragList{F, F}});
305 Section->CurFragList = &Subsections[I].second;
306 CurFrag = Section->CurFragList->Tail;
308 return getAssembler().registerSection(*Section);
311 void MCObjectStreamer::switchSectionNoPrint(MCSection *Section) {
312 MCStreamer::switchSectionNoPrint(Section);
313 changeSection(Section, 0);
316 void MCObjectStreamer::emitAssignment(MCSymbol *Symbol, const MCExpr *Value) {
317 getAssembler().registerSymbol(*Symbol);
318 MCStreamer::emitAssignment(Symbol, Value);
319 emitPendingAssignments(Symbol);
322 void MCObjectStreamer::emitConditionalAssignment(MCSymbol *Symbol,
323 const MCExpr *Value) {
324 const MCSymbol *Target = &cast<MCSymbolRefExpr>(*Value).getSymbol();
326 // If the symbol already exists, emit the assignment. Otherwise, emit it
327 // later only if the symbol is also emitted.
328 if (Target->isRegistered())
329 emitAssignment(Symbol, Value);
330 else
331 pendingAssignments[Target].push_back({Symbol, Value});
334 bool MCObjectStreamer::mayHaveInstructions(MCSection &Sec) const {
335 return Sec.hasInstructions();
338 void MCObjectStreamer::emitInstruction(const MCInst &Inst,
339 const MCSubtargetInfo &STI) {
340 const MCSection &Sec = *getCurrentSectionOnly();
341 if (Sec.isVirtualSection()) {
342 getContext().reportError(Inst.getLoc(), Twine(Sec.getVirtualSectionKind()) +
343 " section '" + Sec.getName() +
344 "' cannot have instructions");
345 return;
347 emitInstructionImpl(Inst, STI);
350 void MCObjectStreamer::emitInstructionImpl(const MCInst &Inst,
351 const MCSubtargetInfo &STI) {
352 MCStreamer::emitInstruction(Inst, STI);
354 MCSection *Sec = getCurrentSectionOnly();
355 Sec->setHasInstructions(true);
357 // Now that a machine instruction has been assembled into this section, make
358 // a line entry for any .loc directive that has been seen.
359 MCDwarfLineEntry::make(this, getCurrentSectionOnly());
361 // If this instruction doesn't need relaxation, just emit it as data.
362 MCAssembler &Assembler = getAssembler();
363 MCAsmBackend &Backend = Assembler.getBackend();
364 if (!(Backend.mayNeedRelaxation(Inst, STI) ||
365 Backend.allowEnhancedRelaxation())) {
366 emitInstToData(Inst, STI);
367 return;
370 // Otherwise, relax and emit it as data if either:
371 // - The RelaxAll flag was passed
372 // - Bundling is enabled and this instruction is inside a bundle-locked
373 // group. We want to emit all such instructions into the same data
374 // fragment.
375 if (Assembler.getRelaxAll() ||
376 (Assembler.isBundlingEnabled() && Sec->isBundleLocked())) {
377 MCInst Relaxed = Inst;
378 while (Backend.mayNeedRelaxation(Relaxed, STI))
379 Backend.relaxInstruction(Relaxed, STI);
380 emitInstToData(Relaxed, STI);
381 return;
384 // Otherwise emit to a separate fragment.
385 emitInstToFragment(Inst, STI);
388 void MCObjectStreamer::emitInstToFragment(const MCInst &Inst,
389 const MCSubtargetInfo &STI) {
390 // Always create a new, separate fragment here, because its size can change
391 // during relaxation.
392 MCRelaxableFragment *IF =
393 getContext().allocFragment<MCRelaxableFragment>(Inst, STI);
394 insert(IF);
396 getAssembler().getEmitter().encodeInstruction(Inst, IF->getContents(),
397 IF->getFixups(), STI);
400 #ifndef NDEBUG
401 static const char *const BundlingNotImplementedMsg =
402 "Aligned bundling is not implemented for this object format";
403 #endif
405 void MCObjectStreamer::emitBundleAlignMode(Align Alignment) {
406 llvm_unreachable(BundlingNotImplementedMsg);
409 void MCObjectStreamer::emitBundleLock(bool AlignToEnd) {
410 llvm_unreachable(BundlingNotImplementedMsg);
413 void MCObjectStreamer::emitBundleUnlock() {
414 llvm_unreachable(BundlingNotImplementedMsg);
417 void MCObjectStreamer::emitDwarfLocDirective(unsigned FileNo, unsigned Line,
418 unsigned Column, unsigned Flags,
419 unsigned Isa,
420 unsigned Discriminator,
421 StringRef FileName) {
422 // In case we see two .loc directives in a row, make sure the
423 // first one gets a line entry.
424 MCDwarfLineEntry::make(this, getCurrentSectionOnly());
426 this->MCStreamer::emitDwarfLocDirective(FileNo, Line, Column, Flags, Isa,
427 Discriminator, FileName);
430 static const MCExpr *buildSymbolDiff(MCObjectStreamer &OS, const MCSymbol *A,
431 const MCSymbol *B, SMLoc Loc) {
432 MCContext &Context = OS.getContext();
433 MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
434 const MCExpr *ARef = MCSymbolRefExpr::create(A, Variant, Context);
435 const MCExpr *BRef = MCSymbolRefExpr::create(B, Variant, Context);
436 const MCExpr *AddrDelta =
437 MCBinaryExpr::create(MCBinaryExpr::Sub, ARef, BRef, Context, Loc);
438 return AddrDelta;
441 static void emitDwarfSetLineAddr(MCObjectStreamer &OS,
442 MCDwarfLineTableParams Params,
443 int64_t LineDelta, const MCSymbol *Label,
444 int PointerSize) {
445 // emit the sequence to set the address
446 OS.emitIntValue(dwarf::DW_LNS_extended_op, 1);
447 OS.emitULEB128IntValue(PointerSize + 1);
448 OS.emitIntValue(dwarf::DW_LNE_set_address, 1);
449 OS.emitSymbolValue(Label, PointerSize);
451 // emit the sequence for the LineDelta (from 1) and a zero address delta.
452 MCDwarfLineAddr::Emit(&OS, Params, LineDelta, 0);
455 void MCObjectStreamer::emitDwarfAdvanceLineAddr(int64_t LineDelta,
456 const MCSymbol *LastLabel,
457 const MCSymbol *Label,
458 unsigned PointerSize) {
459 if (!LastLabel) {
460 emitDwarfSetLineAddr(*this, Assembler->getDWARFLinetableParams(), LineDelta,
461 Label, PointerSize);
462 return;
464 const MCExpr *AddrDelta = buildSymbolDiff(*this, Label, LastLabel, SMLoc());
465 insert(getContext().allocFragment<MCDwarfLineAddrFragment>(LineDelta,
466 *AddrDelta));
469 void MCObjectStreamer::emitDwarfLineEndEntry(MCSection *Section,
470 MCSymbol *LastLabel,
471 MCSymbol *EndLabel) {
472 // Emit a DW_LNE_end_sequence into the line table. When EndLabel is null, it
473 // means we should emit the entry for the end of the section and therefore we
474 // use the section end label for the reference label. After having the
475 // appropriate reference label, we emit the address delta and use INT64_MAX as
476 // the line delta which is the signal that this is actually a
477 // DW_LNE_end_sequence.
478 if (!EndLabel)
479 EndLabel = endSection(Section);
481 // Switch back the dwarf line section, in case endSection had to switch the
482 // section.
483 MCContext &Ctx = getContext();
484 switchSection(Ctx.getObjectFileInfo()->getDwarfLineSection());
486 const MCAsmInfo *AsmInfo = Ctx.getAsmInfo();
487 emitDwarfAdvanceLineAddr(INT64_MAX, LastLabel, EndLabel,
488 AsmInfo->getCodePointerSize());
491 void MCObjectStreamer::emitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel,
492 const MCSymbol *Label,
493 SMLoc Loc) {
494 const MCExpr *AddrDelta = buildSymbolDiff(*this, Label, LastLabel, Loc);
495 insert(getContext().allocFragment<MCDwarfCallFrameFragment>(*AddrDelta));
498 void MCObjectStreamer::emitCVLocDirective(unsigned FunctionId, unsigned FileNo,
499 unsigned Line, unsigned Column,
500 bool PrologueEnd, bool IsStmt,
501 StringRef FileName, SMLoc Loc) {
502 // Validate the directive.
503 if (!checkCVLocSection(FunctionId, FileNo, Loc))
504 return;
506 // Emit a label at the current position and record it in the CodeViewContext.
507 MCSymbol *LineSym = getContext().createTempSymbol();
508 emitLabel(LineSym);
509 getContext().getCVContext().recordCVLoc(getContext(), LineSym, FunctionId,
510 FileNo, Line, Column, PrologueEnd,
511 IsStmt);
514 void MCObjectStreamer::emitCVLinetableDirective(unsigned FunctionId,
515 const MCSymbol *Begin,
516 const MCSymbol *End) {
517 getContext().getCVContext().emitLineTableForFunction(*this, FunctionId, Begin,
518 End);
519 this->MCStreamer::emitCVLinetableDirective(FunctionId, Begin, End);
522 void MCObjectStreamer::emitCVInlineLinetableDirective(
523 unsigned PrimaryFunctionId, unsigned SourceFileId, unsigned SourceLineNum,
524 const MCSymbol *FnStartSym, const MCSymbol *FnEndSym) {
525 getContext().getCVContext().emitInlineLineTableForFunction(
526 *this, PrimaryFunctionId, SourceFileId, SourceLineNum, FnStartSym,
527 FnEndSym);
528 this->MCStreamer::emitCVInlineLinetableDirective(
529 PrimaryFunctionId, SourceFileId, SourceLineNum, FnStartSym, FnEndSym);
532 void MCObjectStreamer::emitCVDefRangeDirective(
533 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
534 StringRef FixedSizePortion) {
535 getContext().getCVContext().emitDefRange(*this, Ranges, FixedSizePortion);
536 // Attach labels that were pending before we created the defrange fragment to
537 // the beginning of the new fragment.
538 this->MCStreamer::emitCVDefRangeDirective(Ranges, FixedSizePortion);
541 void MCObjectStreamer::emitCVStringTableDirective() {
542 getContext().getCVContext().emitStringTable(*this);
544 void MCObjectStreamer::emitCVFileChecksumsDirective() {
545 getContext().getCVContext().emitFileChecksums(*this);
548 void MCObjectStreamer::emitCVFileChecksumOffsetDirective(unsigned FileNo) {
549 getContext().getCVContext().emitFileChecksumOffset(*this, FileNo);
552 void MCObjectStreamer::emitBytes(StringRef Data) {
553 MCDwarfLineEntry::make(this, getCurrentSectionOnly());
554 MCDataFragment *DF = getOrCreateDataFragment();
555 DF->getContents().append(Data.begin(), Data.end());
558 void MCObjectStreamer::emitValueToAlignment(Align Alignment, int64_t Value,
559 unsigned ValueSize,
560 unsigned MaxBytesToEmit) {
561 if (MaxBytesToEmit == 0)
562 MaxBytesToEmit = Alignment.value();
563 insert(getContext().allocFragment<MCAlignFragment>(
564 Alignment, Value, ValueSize, MaxBytesToEmit));
566 // Update the maximum alignment on the current section if necessary.
567 MCSection *CurSec = getCurrentSectionOnly();
568 CurSec->ensureMinAlignment(Alignment);
571 void MCObjectStreamer::emitCodeAlignment(Align Alignment,
572 const MCSubtargetInfo *STI,
573 unsigned MaxBytesToEmit) {
574 emitValueToAlignment(Alignment, 0, 1, MaxBytesToEmit);
575 cast<MCAlignFragment>(getCurrentFragment())->setEmitNops(true, STI);
578 void MCObjectStreamer::emitValueToOffset(const MCExpr *Offset,
579 unsigned char Value,
580 SMLoc Loc) {
581 insert(getContext().allocFragment<MCOrgFragment>(*Offset, Value, Loc));
584 // Associate DTPRel32 fixup with data and resize data area
585 void MCObjectStreamer::emitDTPRel32Value(const MCExpr *Value) {
586 MCDataFragment *DF = getOrCreateDataFragment();
587 DF->getFixups().push_back(MCFixup::create(DF->getContents().size(),
588 Value, FK_DTPRel_4));
589 DF->getContents().resize(DF->getContents().size() + 4, 0);
592 // Associate DTPRel64 fixup with data and resize data area
593 void MCObjectStreamer::emitDTPRel64Value(const MCExpr *Value) {
594 MCDataFragment *DF = getOrCreateDataFragment();
595 DF->getFixups().push_back(MCFixup::create(DF->getContents().size(),
596 Value, FK_DTPRel_8));
597 DF->getContents().resize(DF->getContents().size() + 8, 0);
600 // Associate TPRel32 fixup with data and resize data area
601 void MCObjectStreamer::emitTPRel32Value(const MCExpr *Value) {
602 MCDataFragment *DF = getOrCreateDataFragment();
603 DF->getFixups().push_back(MCFixup::create(DF->getContents().size(),
604 Value, FK_TPRel_4));
605 DF->getContents().resize(DF->getContents().size() + 4, 0);
608 // Associate TPRel64 fixup with data and resize data area
609 void MCObjectStreamer::emitTPRel64Value(const MCExpr *Value) {
610 MCDataFragment *DF = getOrCreateDataFragment();
611 DF->getFixups().push_back(MCFixup::create(DF->getContents().size(),
612 Value, FK_TPRel_8));
613 DF->getContents().resize(DF->getContents().size() + 8, 0);
616 // Associate GPRel32 fixup with data and resize data area
617 void MCObjectStreamer::emitGPRel32Value(const MCExpr *Value) {
618 MCDataFragment *DF = getOrCreateDataFragment();
619 DF->getFixups().push_back(
620 MCFixup::create(DF->getContents().size(), Value, FK_GPRel_4));
621 DF->getContents().resize(DF->getContents().size() + 4, 0);
624 // Associate GPRel64 fixup with data and resize data area
625 void MCObjectStreamer::emitGPRel64Value(const MCExpr *Value) {
626 MCDataFragment *DF = getOrCreateDataFragment();
627 DF->getFixups().push_back(
628 MCFixup::create(DF->getContents().size(), Value, FK_GPRel_4));
629 DF->getContents().resize(DF->getContents().size() + 8, 0);
632 static std::optional<std::pair<bool, std::string>>
633 getOffsetAndDataFragment(const MCSymbol &Symbol, uint32_t &RelocOffset,
634 MCDataFragment *&DF) {
635 if (Symbol.isVariable()) {
636 const MCExpr *SymbolExpr = Symbol.getVariableValue();
637 MCValue OffsetVal;
638 if(!SymbolExpr->evaluateAsRelocatable(OffsetVal, nullptr, nullptr))
639 return std::make_pair(false,
640 std::string("symbol in .reloc offset is not "
641 "relocatable"));
642 if (OffsetVal.isAbsolute()) {
643 RelocOffset = OffsetVal.getConstant();
644 MCFragment *Fragment = Symbol.getFragment();
645 // FIXME Support symbols with no DF. For example:
646 // .reloc .data, ENUM_VALUE, <some expr>
647 if (!Fragment || Fragment->getKind() != MCFragment::FT_Data)
648 return std::make_pair(false,
649 std::string("symbol in offset has no data "
650 "fragment"));
651 DF = cast<MCDataFragment>(Fragment);
652 return std::nullopt;
655 if (OffsetVal.getSymB())
656 return std::make_pair(false,
657 std::string(".reloc symbol offset is not "
658 "representable"));
660 const MCSymbolRefExpr &SRE = cast<MCSymbolRefExpr>(*OffsetVal.getSymA());
661 if (!SRE.getSymbol().isDefined())
662 return std::make_pair(false,
663 std::string("symbol used in the .reloc offset is "
664 "not defined"));
666 if (SRE.getSymbol().isVariable())
667 return std::make_pair(false,
668 std::string("symbol used in the .reloc offset is "
669 "variable"));
671 MCFragment *Fragment = SRE.getSymbol().getFragment();
672 // FIXME Support symbols with no DF. For example:
673 // .reloc .data, ENUM_VALUE, <some expr>
674 if (!Fragment || Fragment->getKind() != MCFragment::FT_Data)
675 return std::make_pair(false,
676 std::string("symbol in offset has no data "
677 "fragment"));
678 RelocOffset = SRE.getSymbol().getOffset() + OffsetVal.getConstant();
679 DF = cast<MCDataFragment>(Fragment);
680 } else {
681 RelocOffset = Symbol.getOffset();
682 MCFragment *Fragment = Symbol.getFragment();
683 // FIXME Support symbols with no DF. For example:
684 // .reloc .data, ENUM_VALUE, <some expr>
685 if (!Fragment || Fragment->getKind() != MCFragment::FT_Data)
686 return std::make_pair(false,
687 std::string("symbol in offset has no data "
688 "fragment"));
689 DF = cast<MCDataFragment>(Fragment);
691 return std::nullopt;
694 std::optional<std::pair<bool, std::string>>
695 MCObjectStreamer::emitRelocDirective(const MCExpr &Offset, StringRef Name,
696 const MCExpr *Expr, SMLoc Loc,
697 const MCSubtargetInfo &STI) {
698 std::optional<MCFixupKind> MaybeKind =
699 Assembler->getBackend().getFixupKind(Name);
700 if (!MaybeKind)
701 return std::make_pair(true, std::string("unknown relocation name"));
703 MCFixupKind Kind = *MaybeKind;
704 if (Expr)
705 visitUsedExpr(*Expr);
706 else
707 Expr =
708 MCSymbolRefExpr::create(getContext().createTempSymbol(), getContext());
710 MCDataFragment *DF = getOrCreateDataFragment(&STI);
711 MCValue OffsetVal;
712 if (!Offset.evaluateAsRelocatable(OffsetVal, nullptr, nullptr))
713 return std::make_pair(false,
714 std::string(".reloc offset is not relocatable"));
715 if (OffsetVal.isAbsolute()) {
716 if (OffsetVal.getConstant() < 0)
717 return std::make_pair(false, std::string(".reloc offset is negative"));
718 DF->getFixups().push_back(
719 MCFixup::create(OffsetVal.getConstant(), Expr, Kind, Loc));
720 return std::nullopt;
722 if (OffsetVal.getSymB())
723 return std::make_pair(false,
724 std::string(".reloc offset is not representable"));
726 const MCSymbolRefExpr &SRE = cast<MCSymbolRefExpr>(*OffsetVal.getSymA());
727 const MCSymbol &Symbol = SRE.getSymbol();
728 if (Symbol.isDefined()) {
729 uint32_t SymbolOffset = 0;
730 std::optional<std::pair<bool, std::string>> Error =
731 getOffsetAndDataFragment(Symbol, SymbolOffset, DF);
733 if (Error != std::nullopt)
734 return Error;
736 DF->getFixups().push_back(
737 MCFixup::create(SymbolOffset + OffsetVal.getConstant(),
738 Expr, Kind, Loc));
739 return std::nullopt;
742 PendingFixups.emplace_back(
743 &SRE.getSymbol(), DF,
744 MCFixup::create(OffsetVal.getConstant(), Expr, Kind, Loc));
745 return std::nullopt;
748 void MCObjectStreamer::emitFill(const MCExpr &NumBytes, uint64_t FillValue,
749 SMLoc Loc) {
750 assert(getCurrentSectionOnly() && "need a section");
751 insert(
752 getContext().allocFragment<MCFillFragment>(FillValue, 1, NumBytes, Loc));
755 void MCObjectStreamer::emitFill(const MCExpr &NumValues, int64_t Size,
756 int64_t Expr, SMLoc Loc) {
757 int64_t IntNumValues;
758 // Do additional checking now if we can resolve the value.
759 if (NumValues.evaluateAsAbsolute(IntNumValues, getAssemblerPtr())) {
760 if (IntNumValues < 0) {
761 getContext().getSourceManager()->PrintMessage(
762 Loc, SourceMgr::DK_Warning,
763 "'.fill' directive with negative repeat count has no effect");
764 return;
766 // Emit now if we can for better errors.
767 int64_t NonZeroSize = Size > 4 ? 4 : Size;
768 Expr &= ~0ULL >> (64 - NonZeroSize * 8);
769 for (uint64_t i = 0, e = IntNumValues; i != e; ++i) {
770 emitIntValue(Expr, NonZeroSize);
771 if (NonZeroSize < Size)
772 emitIntValue(0, Size - NonZeroSize);
774 return;
777 // Otherwise emit as fragment.
778 assert(getCurrentSectionOnly() && "need a section");
779 insert(
780 getContext().allocFragment<MCFillFragment>(Expr, Size, NumValues, Loc));
783 void MCObjectStreamer::emitNops(int64_t NumBytes, int64_t ControlledNopLength,
784 SMLoc Loc, const MCSubtargetInfo &STI) {
785 assert(getCurrentSectionOnly() && "need a section");
786 insert(getContext().allocFragment<MCNopsFragment>(
787 NumBytes, ControlledNopLength, Loc, STI));
790 void MCObjectStreamer::emitFileDirective(StringRef Filename) {
791 MCAssembler &Asm = getAssembler();
792 Asm.getWriter().addFileName(Asm, Filename);
795 void MCObjectStreamer::emitFileDirective(StringRef Filename,
796 StringRef CompilerVersion,
797 StringRef TimeStamp,
798 StringRef Description) {
799 MCObjectWriter &W = getAssembler().getWriter();
800 W.addFileName(getAssembler(), Filename);
801 if (CompilerVersion.size())
802 W.setCompilerVersion(CompilerVersion);
803 // TODO: add TimeStamp and Description to .file symbol table entry
804 // with the integrated assembler.
807 void MCObjectStreamer::emitAddrsig() {
808 getAssembler().getWriter().emitAddrsigSection();
811 void MCObjectStreamer::emitAddrsigSym(const MCSymbol *Sym) {
812 getAssembler().getWriter().addAddrsigSymbol(Sym);
815 void MCObjectStreamer::finishImpl() {
816 getContext().RemapDebugPaths();
818 // If we are generating dwarf for assembly source files dump out the sections.
819 if (getContext().getGenDwarfForAssembly())
820 MCGenDwarfInfo::Emit(this);
822 // Dump out the dwarf file & directory tables and line tables.
823 MCDwarfLineTable::emit(this, getAssembler().getDWARFLinetableParams());
825 // Emit pseudo probes for the current module.
826 MCPseudoProbeTable::emit(this);
828 resolvePendingFixups();
829 getAssembler().Finish();