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