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