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