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