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