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 //===----------------------------------------------------------------------===// 8 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; 26 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); 39 } 40 41 MCObjectStreamer::~MCObjectStreamer() = default; 42 43 MCAssembler *MCObjectStreamer::getAssemblerPtr() { 44 if (getUseAssemblerInfoForParsing()) 45 return Assembler.get(); 46 return nullptr; 47 } 48 49 // When fixup's offset is a forward declared label, e.g.: 50 // 51 // .reloc 1f, R_MIPS_JALR, foo 52 // 1: nop 53 // 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; 62 } 63 PendingFixup.Fixup.setOffset(PendingFixup.Sym->getOffset() + 64 PendingFixup.Fixup.getOffset()); 65 66 // If the location symbol to relocate is in MCEncodedFragment, 67 // put the Fixup into location symbol's fragment. Otherwise 68 // put into PendingFixup.DF 69 MCFragment *SymFragment = PendingFixup.Sym->getFragment(); 70 if (auto *F = dyn_cast<MCEncodedFragment>(SymFragment)) 71 F->addFixup(PendingFixup.Fixup); 72 else 73 PendingFixup.DF->addFixup(PendingFixup.Fixup); 74 } 75 PendingFixups.clear(); 76 } 77 78 // As a compile-time optimization, avoid allocating and evaluating an MCExpr 79 // tree for (Hi - Lo) when Hi and Lo are offsets into the same fragment. 80 static std::optional<uint64_t> absoluteSymbolDiff(const MCSymbol *Hi, 81 const MCSymbol *Lo) { 82 assert(Hi && Lo); 83 if (Lo == Hi) 84 return 0; 85 if (Hi->isVariable() || Lo->isVariable()) 86 return std::nullopt; 87 auto *LoF = Lo->getFragment(); 88 if (!LoF || LoF->getKind() != MCFragment::FT_Data || 89 Hi->getFragment() != LoF || LoF->isLinkerRelaxable()) 90 return std::nullopt; 91 92 return Hi->getOffset() - Lo->getOffset(); 93 } 94 95 void MCObjectStreamer::emitAbsoluteSymbolDiff(const MCSymbol *Hi, 96 const MCSymbol *Lo, 97 unsigned Size) { 98 if (std::optional<uint64_t> Diff = absoluteSymbolDiff(Hi, Lo)) 99 emitIntValue(*Diff, Size); 100 else 101 MCStreamer::emitAbsoluteSymbolDiff(Hi, Lo, Size); 102 } 103 104 void MCObjectStreamer::emitAbsoluteSymbolDiffAsULEB128(const MCSymbol *Hi, 105 const MCSymbol *Lo) { 106 if (std::optional<uint64_t> Diff = absoluteSymbolDiff(Hi, Lo)) 107 emitULEB128IntValue(*Diff); 108 else 109 MCStreamer::emitAbsoluteSymbolDiffAsULEB128(Hi, Lo); 110 } 111 112 void MCObjectStreamer::reset() { 113 if (Assembler) { 114 Assembler->reset(); 115 if (getContext().getTargetOptions()) 116 Assembler->setRelaxAll(getContext().getTargetOptions()->MCRelaxAll); 117 } 118 EmitEHFrame = true; 119 EmitDebugFrame = false; 120 MCStreamer::reset(); 121 } 122 123 void MCObjectStreamer::emitFrames(MCAsmBackend *MAB) { 124 if (!getNumFrameInfos()) 125 return; 126 127 if (EmitEHFrame) 128 MCDwarfFrameEmitter::Emit(*this, MAB, true); 129 130 if (EmitDebugFrame) 131 MCDwarfFrameEmitter::Emit(*this, MAB, false); 132 } 133 134 static bool canReuseDataFragment(const MCDataFragment &F, 135 const MCAssembler &Assembler, 136 const MCSubtargetInfo *STI) { 137 if (!F.hasInstructions()) 138 return true; 139 // Do not add data after a linker-relaxable instruction. The difference 140 // between a new label and a label at or before the linker-relaxable 141 // instruction cannot be resolved at assemble-time. 142 if (F.isLinkerRelaxable()) 143 return false; 144 // When bundling is enabled, we don't want to add data to a fragment that 145 // already has instructions (see MCELFStreamer::emitInstToData for details) 146 if (Assembler.isBundlingEnabled()) 147 return false; 148 // If the subtarget is changed mid fragment we start a new fragment to record 149 // the new STI. 150 return !STI || F.getSubtargetInfo() == STI; 151 } 152 153 MCDataFragment * 154 MCObjectStreamer::getOrCreateDataFragment(const MCSubtargetInfo *STI) { 155 auto *F = dyn_cast<MCDataFragment>(getCurrentFragment()); 156 if (!F || !canReuseDataFragment(*F, *Assembler, STI)) { 157 F = getContext().allocFragment<MCDataFragment>(); 158 insert(F); 159 } 160 return F; 161 } 162 163 void MCObjectStreamer::visitUsedSymbol(const MCSymbol &Sym) { 164 Assembler->registerSymbol(Sym); 165 } 166 167 void MCObjectStreamer::emitCFISections(bool EH, bool Debug) { 168 MCStreamer::emitCFISections(EH, Debug); 169 EmitEHFrame = EH; 170 EmitDebugFrame = Debug; 171 } 172 173 void MCObjectStreamer::emitValueImpl(const MCExpr *Value, unsigned Size, 174 SMLoc Loc) { 175 MCStreamer::emitValueImpl(Value, Size, Loc); 176 MCDataFragment *DF = getOrCreateDataFragment(); 177 178 MCDwarfLineEntry::make(this, getCurrentSectionOnly()); 179 180 // Avoid fixups when possible. 181 int64_t AbsValue; 182 if (Value->evaluateAsAbsolute(AbsValue, getAssemblerPtr())) { 183 if (!isUIntN(8 * Size, AbsValue) && !isIntN(8 * Size, AbsValue)) { 184 getContext().reportError( 185 Loc, "value evaluated as " + Twine(AbsValue) + " is out of range."); 186 return; 187 } 188 emitIntValue(AbsValue, Size); 189 return; 190 } 191 DF->addFixup(MCFixup::create(DF->getContents().size(), Value, 192 MCFixup::getDataKindForSize(Size))); 193 DF->appendContents(Size, 0); 194 } 195 196 MCSymbol *MCObjectStreamer::emitCFILabel() { 197 MCSymbol *Label = getContext().createTempSymbol("cfi"); 198 emitLabel(Label); 199 return Label; 200 } 201 202 void MCObjectStreamer::emitCFIStartProcImpl(MCDwarfFrameInfo &Frame) { 203 // We need to create a local symbol to avoid relocations. 204 Frame.Begin = getContext().createTempSymbol(); 205 emitLabel(Frame.Begin); 206 } 207 208 void MCObjectStreamer::emitCFIEndProcImpl(MCDwarfFrameInfo &Frame) { 209 Frame.End = getContext().createTempSymbol(); 210 emitLabel(Frame.End); 211 } 212 213 void MCObjectStreamer::emitLabel(MCSymbol *Symbol, SMLoc Loc) { 214 MCStreamer::emitLabel(Symbol, Loc); 215 // If Symbol is a non-redefiniable variable, emitLabel has reported an error. 216 // Bail out. 217 if (Symbol->isVariable()) 218 return; 219 220 getAssembler().registerSymbol(*Symbol); 221 222 // If there is a current fragment, mark the symbol as pointing into it. 223 // Otherwise queue the label and set its fragment pointer when we emit the 224 // next fragment. 225 MCDataFragment *F = getOrCreateDataFragment(); 226 Symbol->setFragment(F); 227 Symbol->setOffset(F->getContents().size()); 228 229 emitPendingAssignments(Symbol); 230 } 231 232 void MCObjectStreamer::emitPendingAssignments(MCSymbol *Symbol) { 233 auto Assignments = pendingAssignments.find(Symbol); 234 if (Assignments != pendingAssignments.end()) { 235 for (const PendingAssignment &A : Assignments->second) 236 emitAssignment(A.Symbol, A.Value); 237 238 pendingAssignments.erase(Assignments); 239 } 240 } 241 242 // Emit a label at a previously emitted fragment/offset position. This must be 243 // within the currently-active section. 244 void MCObjectStreamer::emitLabelAtPos(MCSymbol *Symbol, SMLoc Loc, 245 MCDataFragment &F, uint64_t Offset) { 246 assert(F.getParent() == getCurrentSectionOnly()); 247 MCStreamer::emitLabel(Symbol, Loc); 248 getAssembler().registerSymbol(*Symbol); 249 Symbol->setFragment(&F); 250 Symbol->setOffset(Offset); 251 } 252 253 void MCObjectStreamer::emitULEB128Value(const MCExpr *Value) { 254 int64_t IntValue; 255 if (Value->evaluateAsAbsolute(IntValue, getAssembler())) { 256 emitULEB128IntValue(IntValue); 257 return; 258 } 259 insert(getContext().allocFragment<MCLEBFragment>(*Value, false)); 260 } 261 262 void MCObjectStreamer::emitSLEB128Value(const MCExpr *Value) { 263 int64_t IntValue; 264 if (Value->evaluateAsAbsolute(IntValue, getAssembler())) { 265 emitSLEB128IntValue(IntValue); 266 return; 267 } 268 insert(getContext().allocFragment<MCLEBFragment>(*Value, true)); 269 } 270 271 void MCObjectStreamer::emitWeakReference(MCSymbol *Alias, 272 const MCSymbol *Target) { 273 reportFatalUsageError("this file format doesn't support weak aliases"); 274 } 275 276 void MCObjectStreamer::changeSection(MCSection *Section, uint32_t Subsection) { 277 changeSectionImpl(Section, Subsection); 278 } 279 280 bool MCObjectStreamer::changeSectionImpl(MCSection *Section, 281 uint32_t Subsection) { 282 assert(Section && "Cannot switch to a null section!"); 283 getContext().clearDwarfLocSeen(); 284 285 auto &Subsections = Section->Subsections; 286 size_t I = 0, E = Subsections.size(); 287 while (I != E && Subsections[I].first < Subsection) 288 ++I; 289 // If the subsection number is not in the sorted Subsections list, create a 290 // new fragment list. 291 if (I == E || Subsections[I].first != Subsection) { 292 auto *F = getContext().allocFragment<MCDataFragment>(); 293 F->setParent(Section); 294 Subsections.insert(Subsections.begin() + I, 295 {Subsection, MCSection::FragList{F, F}}); 296 } 297 Section->CurFragList = &Subsections[I].second; 298 CurFrag = Section->CurFragList->Tail; 299 300 return getAssembler().registerSection(*Section); 301 } 302 303 void MCObjectStreamer::switchSectionNoPrint(MCSection *Section) { 304 MCStreamer::switchSectionNoPrint(Section); 305 changeSection(Section, 0); 306 } 307 308 void MCObjectStreamer::emitAssignment(MCSymbol *Symbol, const MCExpr *Value) { 309 getAssembler().registerSymbol(*Symbol); 310 MCStreamer::emitAssignment(Symbol, Value); 311 emitPendingAssignments(Symbol); 312 } 313 314 void MCObjectStreamer::emitConditionalAssignment(MCSymbol *Symbol, 315 const MCExpr *Value) { 316 const MCSymbol *Target = &cast<MCSymbolRefExpr>(*Value).getSymbol(); 317 318 // If the symbol already exists, emit the assignment. Otherwise, emit it 319 // later only if the symbol is also emitted. 320 if (Target->isRegistered()) 321 emitAssignment(Symbol, Value); 322 else 323 pendingAssignments[Target].push_back({Symbol, Value}); 324 } 325 326 bool MCObjectStreamer::mayHaveInstructions(MCSection &Sec) const { 327 return Sec.hasInstructions(); 328 } 329 330 void MCObjectStreamer::emitInstruction(const MCInst &Inst, 331 const MCSubtargetInfo &STI) { 332 const MCSection &Sec = *getCurrentSectionOnly(); 333 if (Sec.isVirtualSection()) { 334 getContext().reportError(Inst.getLoc(), Twine(Sec.getVirtualSectionKind()) + 335 " section '" + Sec.getName() + 336 "' cannot have instructions"); 337 return; 338 } 339 emitInstructionImpl(Inst, STI); 340 } 341 342 void MCObjectStreamer::emitInstructionImpl(const MCInst &Inst, 343 const MCSubtargetInfo &STI) { 344 MCStreamer::emitInstruction(Inst, STI); 345 346 MCSection *Sec = getCurrentSectionOnly(); 347 Sec->setHasInstructions(true); 348 349 // Now that a machine instruction has been assembled into this section, make 350 // a line entry for any .loc directive that has been seen. 351 MCDwarfLineEntry::make(this, getCurrentSectionOnly()); 352 353 // If this instruction doesn't need relaxation, just emit it as data. 354 MCAssembler &Assembler = getAssembler(); 355 MCAsmBackend &Backend = Assembler.getBackend(); 356 if (!(Backend.mayNeedRelaxation(Inst.getOpcode(), Inst.getOperands(), STI) || 357 Backend.allowEnhancedRelaxation())) { 358 emitInstToData(Inst, STI); 359 return; 360 } 361 362 // Otherwise, relax and emit it as data if either: 363 // - The RelaxAll flag was passed 364 // - Bundling is enabled and this instruction is inside a bundle-locked 365 // group. We want to emit all such instructions into the same data 366 // fragment. 367 if (Assembler.getRelaxAll() || 368 (Assembler.isBundlingEnabled() && Sec->isBundleLocked())) { 369 MCInst Relaxed = Inst; 370 while (Backend.mayNeedRelaxation(Relaxed.getOpcode(), Relaxed.getOperands(), 371 STI)) 372 Backend.relaxInstruction(Relaxed, STI); 373 emitInstToData(Relaxed, STI); 374 return; 375 } 376 377 // Otherwise emit to a separate fragment. 378 emitInstToFragment(Inst, STI); 379 } 380 381 void MCObjectStreamer::emitInstToData(const MCInst &Inst, 382 const MCSubtargetInfo &STI) { 383 MCDataFragment *DF = getOrCreateDataFragment(); 384 SmallVector<MCFixup, 1> Fixups; 385 SmallString<256> Code; 386 getAssembler().getEmitter().encodeInstruction(Inst, Code, Fixups, STI); 387 388 auto CodeOffset = DF->getContents().size(); 389 for (MCFixup &Fixup : Fixups) 390 Fixup.setOffset(Fixup.getOffset() + CodeOffset); 391 if (!Fixups.empty()) 392 DF->appendFixups(Fixups); 393 DF->setHasInstructions(STI); 394 DF->appendContents(Code); 395 } 396 397 void MCObjectStreamer::emitInstToFragment(const MCInst &Inst, 398 const MCSubtargetInfo &STI) { 399 // Always create a new, separate fragment here, because its size can change 400 // during relaxation. 401 MCRelaxableFragment *IF = 402 getContext().allocFragment<MCRelaxableFragment>(STI); 403 insert(IF); 404 IF->setInst(Inst); 405 406 SmallVector<MCFixup, 1> Fixups; 407 getAssembler().getEmitter().encodeInstruction( 408 Inst, IF->getContentsForAppending(), Fixups, STI); 409 IF->doneAppending(); 410 IF->appendFixups(Fixups); 411 412 for (auto &Fixup : Fixups) { 413 if (Fixup.isLinkerRelaxable()) { 414 IF->setLinkerRelaxable(); 415 getCurrentSectionOnly()->setLinkerRelaxable(); 416 } 417 } 418 } 419 420 #ifndef NDEBUG 421 static const char *const BundlingNotImplementedMsg = 422 "Aligned bundling is not implemented for this object format"; 423 #endif 424 425 void MCObjectStreamer::emitBundleAlignMode(Align Alignment) { 426 llvm_unreachable(BundlingNotImplementedMsg); 427 } 428 429 void MCObjectStreamer::emitBundleLock(bool AlignToEnd) { 430 llvm_unreachable(BundlingNotImplementedMsg); 431 } 432 433 void MCObjectStreamer::emitBundleUnlock() { 434 llvm_unreachable(BundlingNotImplementedMsg); 435 } 436 437 void MCObjectStreamer::emitDwarfLocDirective(unsigned FileNo, unsigned Line, 438 unsigned Column, unsigned Flags, 439 unsigned Isa, 440 unsigned Discriminator, 441 StringRef FileName, 442 StringRef Comment) { 443 // In case we see two .loc directives in a row, make sure the 444 // first one gets a line entry. 445 MCDwarfLineEntry::make(this, getCurrentSectionOnly()); 446 447 this->MCStreamer::emitDwarfLocDirective(FileNo, Line, Column, Flags, Isa, 448 Discriminator, FileName, Comment); 449 } 450 451 static const MCExpr *buildSymbolDiff(MCObjectStreamer &OS, const MCSymbol *A, 452 const MCSymbol *B, SMLoc Loc) { 453 MCContext &Context = OS.getContext(); 454 const MCExpr *ARef = MCSymbolRefExpr::create(A, Context); 455 const MCExpr *BRef = MCSymbolRefExpr::create(B, Context); 456 const MCExpr *AddrDelta = 457 MCBinaryExpr::create(MCBinaryExpr::Sub, ARef, BRef, Context, Loc); 458 return AddrDelta; 459 } 460 461 static void emitDwarfSetLineAddr(MCObjectStreamer &OS, 462 MCDwarfLineTableParams Params, 463 int64_t LineDelta, const MCSymbol *Label, 464 int PointerSize) { 465 // emit the sequence to set the address 466 OS.emitIntValue(dwarf::DW_LNS_extended_op, 1); 467 OS.emitULEB128IntValue(PointerSize + 1); 468 OS.emitIntValue(dwarf::DW_LNE_set_address, 1); 469 OS.emitSymbolValue(Label, PointerSize); 470 471 // emit the sequence for the LineDelta (from 1) and a zero address delta. 472 MCDwarfLineAddr::Emit(&OS, Params, LineDelta, 0); 473 } 474 475 void MCObjectStreamer::emitDwarfAdvanceLineAddr(int64_t LineDelta, 476 const MCSymbol *LastLabel, 477 const MCSymbol *Label, 478 unsigned PointerSize) { 479 if (!LastLabel) { 480 emitDwarfSetLineAddr(*this, Assembler->getDWARFLinetableParams(), LineDelta, 481 Label, PointerSize); 482 return; 483 } 484 485 // If the two labels are within the same fragment, then the address-offset is 486 // already a fixed constant and is not relaxable. Emit the advance-line-addr 487 // data immediately to save time and memory. 488 if (auto OptAddrDelta = absoluteSymbolDiff(Label, LastLabel)) { 489 SmallString<16> Tmp; 490 MCDwarfLineAddr::encode(getContext(), Assembler->getDWARFLinetableParams(), 491 LineDelta, *OptAddrDelta, Tmp); 492 emitBytes(Tmp); 493 return; 494 } 495 496 const MCExpr *AddrDelta = buildSymbolDiff(*this, Label, LastLabel, SMLoc()); 497 insert(getContext().allocFragment<MCDwarfLineAddrFragment>(LineDelta, 498 *AddrDelta)); 499 } 500 501 void MCObjectStreamer::emitDwarfLineEndEntry(MCSection *Section, 502 MCSymbol *LastLabel, 503 MCSymbol *EndLabel) { 504 // Emit a DW_LNE_end_sequence into the line table. When EndLabel is null, it 505 // means we should emit the entry for the end of the section and therefore we 506 // use the section end label for the reference label. After having the 507 // appropriate reference label, we emit the address delta and use INT64_MAX as 508 // the line delta which is the signal that this is actually a 509 // DW_LNE_end_sequence. 510 if (!EndLabel) 511 EndLabel = endSection(Section); 512 513 // Switch back the dwarf line section, in case endSection had to switch the 514 // section. 515 MCContext &Ctx = getContext(); 516 switchSection(Ctx.getObjectFileInfo()->getDwarfLineSection()); 517 518 const MCAsmInfo *AsmInfo = Ctx.getAsmInfo(); 519 emitDwarfAdvanceLineAddr(INT64_MAX, LastLabel, EndLabel, 520 AsmInfo->getCodePointerSize()); 521 } 522 523 void MCObjectStreamer::emitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel, 524 const MCSymbol *Label, 525 SMLoc Loc) { 526 const MCExpr *AddrDelta = buildSymbolDiff(*this, Label, LastLabel, Loc); 527 insert(getContext().allocFragment<MCDwarfCallFrameFragment>(*AddrDelta)); 528 } 529 530 void MCObjectStreamer::emitCVLocDirective(unsigned FunctionId, unsigned FileNo, 531 unsigned Line, unsigned Column, 532 bool PrologueEnd, bool IsStmt, 533 StringRef FileName, SMLoc Loc) { 534 // Validate the directive. 535 if (!checkCVLocSection(FunctionId, FileNo, Loc)) 536 return; 537 538 // Emit a label at the current position and record it in the CodeViewContext. 539 MCSymbol *LineSym = getContext().createTempSymbol(); 540 emitLabel(LineSym); 541 getContext().getCVContext().recordCVLoc(getContext(), LineSym, FunctionId, 542 FileNo, Line, Column, PrologueEnd, 543 IsStmt); 544 } 545 546 void MCObjectStreamer::emitCVLinetableDirective(unsigned FunctionId, 547 const MCSymbol *Begin, 548 const MCSymbol *End) { 549 getContext().getCVContext().emitLineTableForFunction(*this, FunctionId, Begin, 550 End); 551 this->MCStreamer::emitCVLinetableDirective(FunctionId, Begin, End); 552 } 553 554 void MCObjectStreamer::emitCVInlineLinetableDirective( 555 unsigned PrimaryFunctionId, unsigned SourceFileId, unsigned SourceLineNum, 556 const MCSymbol *FnStartSym, const MCSymbol *FnEndSym) { 557 getContext().getCVContext().emitInlineLineTableForFunction( 558 *this, PrimaryFunctionId, SourceFileId, SourceLineNum, FnStartSym, 559 FnEndSym); 560 this->MCStreamer::emitCVInlineLinetableDirective( 561 PrimaryFunctionId, SourceFileId, SourceLineNum, FnStartSym, FnEndSym); 562 } 563 564 void MCObjectStreamer::emitCVDefRangeDirective( 565 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges, 566 StringRef FixedSizePortion) { 567 getContext().getCVContext().emitDefRange(*this, Ranges, FixedSizePortion); 568 // Attach labels that were pending before we created the defrange fragment to 569 // the beginning of the new fragment. 570 this->MCStreamer::emitCVDefRangeDirective(Ranges, FixedSizePortion); 571 } 572 573 void MCObjectStreamer::emitCVStringTableDirective() { 574 getContext().getCVContext().emitStringTable(*this); 575 } 576 void MCObjectStreamer::emitCVFileChecksumsDirective() { 577 getContext().getCVContext().emitFileChecksums(*this); 578 } 579 580 void MCObjectStreamer::emitCVFileChecksumOffsetDirective(unsigned FileNo) { 581 getContext().getCVContext().emitFileChecksumOffset(*this, FileNo); 582 } 583 584 void MCObjectStreamer::emitBytes(StringRef Data) { 585 MCDwarfLineEntry::make(this, getCurrentSectionOnly()); 586 MCDataFragment *DF = getOrCreateDataFragment(); 587 DF->appendContents(ArrayRef(Data.data(), Data.size())); 588 } 589 590 void MCObjectStreamer::emitValueToAlignment(Align Alignment, int64_t Fill, 591 uint8_t FillLen, 592 unsigned MaxBytesToEmit) { 593 if (MaxBytesToEmit == 0) 594 MaxBytesToEmit = Alignment.value(); 595 insert(getContext().allocFragment<MCAlignFragment>(Alignment, Fill, FillLen, 596 MaxBytesToEmit)); 597 598 // Update the maximum alignment on the current section if necessary. 599 MCSection *CurSec = getCurrentSectionOnly(); 600 CurSec->ensureMinAlignment(Alignment); 601 } 602 603 void MCObjectStreamer::emitCodeAlignment(Align Alignment, 604 const MCSubtargetInfo *STI, 605 unsigned MaxBytesToEmit) { 606 emitValueToAlignment(Alignment, 0, 1, MaxBytesToEmit); 607 auto *F = cast<MCAlignFragment>(getCurrentFragment()); 608 F->setEmitNops(true, STI); 609 // With RISC-V style linker relaxation, mark the section as linker-relaxable 610 // if the alignment is larger than the minimum NOP size. 611 unsigned Size; 612 if (getAssembler().getBackend().shouldInsertExtraNopBytesForCodeAlign(*F, 613 Size)) 614 getCurrentSectionOnly()->setLinkerRelaxable(); 615 } 616 617 void MCObjectStreamer::emitValueToOffset(const MCExpr *Offset, 618 unsigned char Value, 619 SMLoc Loc) { 620 insert(getContext().allocFragment<MCOrgFragment>(*Offset, Value, Loc)); 621 } 622 623 static std::optional<std::pair<bool, std::string>> 624 getOffsetAndDataFragment(const MCSymbol &Symbol, uint32_t &RelocOffset, 625 MCDataFragment *&DF) { 626 if (Symbol.isVariable()) { 627 const MCExpr *SymbolExpr = Symbol.getVariableValue(); 628 MCValue OffsetVal; 629 if (!SymbolExpr->evaluateAsRelocatable(OffsetVal, nullptr)) 630 return std::make_pair(false, 631 std::string("symbol in .reloc offset is not " 632 "relocatable")); 633 if (OffsetVal.isAbsolute()) { 634 RelocOffset = OffsetVal.getConstant(); 635 MCFragment *Fragment = Symbol.getFragment(); 636 // FIXME Support symbols with no DF. For example: 637 // .reloc .data, ENUM_VALUE, <some expr> 638 if (!Fragment || Fragment->getKind() != MCFragment::FT_Data) 639 return std::make_pair(false, 640 std::string("symbol in offset has no data " 641 "fragment")); 642 DF = cast<MCDataFragment>(Fragment); 643 return std::nullopt; 644 } 645 646 if (OffsetVal.getSubSym()) 647 return std::make_pair(false, 648 std::string(".reloc symbol offset is not " 649 "representable")); 650 651 const MCSymbol &SA = *OffsetVal.getAddSym(); 652 if (!SA.isDefined()) 653 return std::make_pair(false, 654 std::string("symbol used in the .reloc offset is " 655 "not defined")); 656 657 if (SA.isVariable()) 658 return std::make_pair(false, 659 std::string("symbol used in the .reloc offset is " 660 "variable")); 661 662 MCFragment *Fragment = SA.getFragment(); 663 // FIXME Support symbols with no DF. For example: 664 // .reloc .data, ENUM_VALUE, <some expr> 665 if (!Fragment || Fragment->getKind() != MCFragment::FT_Data) 666 return std::make_pair(false, 667 std::string("symbol in offset has no data " 668 "fragment")); 669 RelocOffset = SA.getOffset() + OffsetVal.getConstant(); 670 DF = cast<MCDataFragment>(Fragment); 671 } else { 672 RelocOffset = Symbol.getOffset(); 673 MCFragment *Fragment = Symbol.getFragment(); 674 // FIXME Support symbols with no DF. For example: 675 // .reloc .data, ENUM_VALUE, <some expr> 676 if (!Fragment || Fragment->getKind() != MCFragment::FT_Data) 677 return std::make_pair(false, 678 std::string("symbol in offset has no data " 679 "fragment")); 680 DF = cast<MCDataFragment>(Fragment); 681 } 682 return std::nullopt; 683 } 684 685 std::optional<std::pair<bool, std::string>> 686 MCObjectStreamer::emitRelocDirective(const MCExpr &Offset, StringRef Name, 687 const MCExpr *Expr, SMLoc Loc, 688 const MCSubtargetInfo &STI) { 689 std::optional<MCFixupKind> MaybeKind = 690 Assembler->getBackend().getFixupKind(Name); 691 if (!MaybeKind) 692 return std::make_pair(true, std::string("unknown relocation name")); 693 694 MCFixupKind Kind = *MaybeKind; 695 if (Expr) 696 visitUsedExpr(*Expr); 697 else 698 Expr = 699 MCSymbolRefExpr::create(getContext().createTempSymbol(), getContext()); 700 701 MCDataFragment *DF = getOrCreateDataFragment(&STI); 702 MCValue OffsetVal; 703 if (!Offset.evaluateAsRelocatable(OffsetVal, nullptr)) 704 return std::make_pair(false, 705 std::string(".reloc offset is not relocatable")); 706 if (OffsetVal.isAbsolute()) { 707 if (OffsetVal.getConstant() < 0) 708 return std::make_pair(false, std::string(".reloc offset is negative")); 709 DF->addFixup(MCFixup::create(OffsetVal.getConstant(), Expr, Kind)); 710 return std::nullopt; 711 } 712 if (OffsetVal.getSubSym()) 713 return std::make_pair(false, 714 std::string(".reloc offset is not representable")); 715 716 const MCSymbol &Symbol = *OffsetVal.getAddSym(); 717 if (Symbol.isDefined()) { 718 uint32_t SymbolOffset = 0; 719 std::optional<std::pair<bool, std::string>> Error = 720 getOffsetAndDataFragment(Symbol, SymbolOffset, DF); 721 722 if (Error != std::nullopt) 723 return Error; 724 725 DF->addFixup( 726 MCFixup::create(SymbolOffset + OffsetVal.getConstant(), Expr, Kind)); 727 return std::nullopt; 728 } 729 730 PendingFixups.emplace_back( 731 &Symbol, DF, MCFixup::create(OffsetVal.getConstant(), Expr, Kind)); 732 return std::nullopt; 733 } 734 735 void MCObjectStreamer::emitFill(const MCExpr &NumBytes, uint64_t FillValue, 736 SMLoc Loc) { 737 assert(getCurrentSectionOnly() && "need a section"); 738 insert( 739 getContext().allocFragment<MCFillFragment>(FillValue, 1, NumBytes, Loc)); 740 } 741 742 void MCObjectStreamer::emitFill(const MCExpr &NumValues, int64_t Size, 743 int64_t Expr, SMLoc Loc) { 744 int64_t IntNumValues; 745 // Do additional checking now if we can resolve the value. 746 if (NumValues.evaluateAsAbsolute(IntNumValues, getAssembler())) { 747 if (IntNumValues < 0) { 748 getContext().getSourceManager()->PrintMessage( 749 Loc, SourceMgr::DK_Warning, 750 "'.fill' directive with negative repeat count has no effect"); 751 return; 752 } 753 // Emit now if we can for better errors. 754 int64_t NonZeroSize = Size > 4 ? 4 : Size; 755 Expr &= ~0ULL >> (64 - NonZeroSize * 8); 756 for (uint64_t i = 0, e = IntNumValues; i != e; ++i) { 757 emitIntValue(Expr, NonZeroSize); 758 if (NonZeroSize < Size) 759 emitIntValue(0, Size - NonZeroSize); 760 } 761 return; 762 } 763 764 // Otherwise emit as fragment. 765 assert(getCurrentSectionOnly() && "need a section"); 766 insert( 767 getContext().allocFragment<MCFillFragment>(Expr, Size, NumValues, Loc)); 768 } 769 770 void MCObjectStreamer::emitNops(int64_t NumBytes, int64_t ControlledNopLength, 771 SMLoc Loc, const MCSubtargetInfo &STI) { 772 assert(getCurrentSectionOnly() && "need a section"); 773 insert(getContext().allocFragment<MCNopsFragment>( 774 NumBytes, ControlledNopLength, Loc, STI)); 775 } 776 777 void MCObjectStreamer::emitFileDirective(StringRef Filename) { 778 MCAssembler &Asm = getAssembler(); 779 Asm.getWriter().addFileName(Filename); 780 } 781 782 void MCObjectStreamer::emitFileDirective(StringRef Filename, 783 StringRef CompilerVersion, 784 StringRef TimeStamp, 785 StringRef Description) { 786 MCObjectWriter &W = getAssembler().getWriter(); 787 W.addFileName(Filename); 788 if (CompilerVersion.size()) 789 W.setCompilerVersion(CompilerVersion); 790 // TODO: add TimeStamp and Description to .file symbol table entry 791 // with the integrated assembler. 792 } 793 794 void MCObjectStreamer::emitAddrsig() { 795 getAssembler().getWriter().emitAddrsigSection(); 796 } 797 798 void MCObjectStreamer::emitAddrsigSym(const MCSymbol *Sym) { 799 getAssembler().getWriter().addAddrsigSymbol(Sym); 800 } 801 802 void MCObjectStreamer::finishImpl() { 803 getContext().RemapDebugPaths(); 804 805 // If we are generating dwarf for assembly source files dump out the sections. 806 if (getContext().getGenDwarfForAssembly()) 807 MCGenDwarfInfo::Emit(this); 808 809 // Dump out the dwarf file & directory tables and line tables. 810 MCDwarfLineTable::emit(this, getAssembler().getDWARFLinetableParams()); 811 812 // Emit pseudo probes for the current module. 813 MCPseudoProbeTable::emit(this); 814 815 resolvePendingFixups(); 816 getAssembler().Finish(); 817 } 818