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> 65 absoluteSymbolDiff(MCAssembler &Asm, const MCSymbol *Hi, const MCSymbol *Lo) { 66 assert(Hi && Lo); 67 if (Asm.getBackendPtr()->requiresDiffExpressionRelocations()) 68 return None; 69 70 if (!Hi->getFragment() || Hi->getFragment() != Lo->getFragment() || 71 Hi->isVariable() || Lo->isVariable()) 72 return None; 73 74 return Hi->getOffset() - Lo->getOffset(); 75 } 76 77 void MCObjectStreamer::emitAbsoluteSymbolDiff(const MCSymbol *Hi, 78 const MCSymbol *Lo, 79 unsigned Size) { 80 if (Optional<uint64_t> Diff = absoluteSymbolDiff(getAssembler(), Hi, Lo)) { 81 EmitIntValue(*Diff, Size); 82 return; 83 } 84 MCStreamer::emitAbsoluteSymbolDiff(Hi, Lo, Size); 85 } 86 87 void MCObjectStreamer::emitAbsoluteSymbolDiffAsULEB128(const MCSymbol *Hi, 88 const MCSymbol *Lo) { 89 if (Optional<uint64_t> Diff = absoluteSymbolDiff(getAssembler(), Hi, Lo)) { 90 EmitULEB128IntValue(*Diff); 91 return; 92 } 93 MCStreamer::emitAbsoluteSymbolDiffAsULEB128(Hi, Lo); 94 } 95 96 void MCObjectStreamer::reset() { 97 if (Assembler) 98 Assembler->reset(); 99 CurInsertionPoint = MCSection::iterator(); 100 EmitEHFrame = true; 101 EmitDebugFrame = false; 102 PendingLabels.clear(); 103 MCStreamer::reset(); 104 } 105 106 void MCObjectStreamer::EmitFrames(MCAsmBackend *MAB) { 107 if (!getNumFrameInfos()) 108 return; 109 110 if (EmitEHFrame) 111 MCDwarfFrameEmitter::Emit(*this, MAB, true); 112 113 if (EmitDebugFrame) 114 MCDwarfFrameEmitter::Emit(*this, MAB, false); 115 } 116 117 MCFragment *MCObjectStreamer::getCurrentFragment() const { 118 assert(getCurrentSectionOnly() && "No current section!"); 119 120 if (CurInsertionPoint != getCurrentSectionOnly()->getFragmentList().begin()) 121 return &*std::prev(CurInsertionPoint); 122 123 return nullptr; 124 } 125 126 static bool CanReuseDataFragment(const MCDataFragment &F, 127 const MCAssembler &Assembler, 128 const MCSubtargetInfo *STI) { 129 if (!F.hasInstructions()) 130 return true; 131 // When bundling is enabled, we don't want to add data to a fragment that 132 // already has instructions (see MCELFStreamer::EmitInstToData for details) 133 if (Assembler.isBundlingEnabled()) 134 return Assembler.getRelaxAll(); 135 // If the subtarget is changed mid fragment we start a new fragment to record 136 // the new STI. 137 return !STI || F.getSubtargetInfo() == STI; 138 } 139 140 MCDataFragment * 141 MCObjectStreamer::getOrCreateDataFragment(const MCSubtargetInfo *STI) { 142 MCDataFragment *F = dyn_cast_or_null<MCDataFragment>(getCurrentFragment()); 143 if (!F || !CanReuseDataFragment(*F, *Assembler, STI)) { 144 F = new MCDataFragment(); 145 insert(F); 146 } 147 return F; 148 } 149 150 MCPaddingFragment *MCObjectStreamer::getOrCreatePaddingFragment() { 151 MCPaddingFragment *F = 152 dyn_cast_or_null<MCPaddingFragment>(getCurrentFragment()); 153 if (!F) { 154 F = new MCPaddingFragment(); 155 insert(F); 156 } 157 return F; 158 } 159 160 void MCObjectStreamer::visitUsedSymbol(const MCSymbol &Sym) { 161 Assembler->registerSymbol(Sym); 162 } 163 164 void MCObjectStreamer::EmitCFISections(bool EH, bool Debug) { 165 MCStreamer::EmitCFISections(EH, Debug); 166 EmitEHFrame = EH; 167 EmitDebugFrame = Debug; 168 } 169 170 void MCObjectStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size, 171 SMLoc Loc) { 172 MCStreamer::EmitValueImpl(Value, Size, Loc); 173 MCDataFragment *DF = getOrCreateDataFragment(); 174 flushPendingLabels(DF, DF->getContents().size()); 175 176 MCDwarfLineEntry::Make(this, getCurrentSectionOnly()); 177 178 // Avoid fixups when possible. 179 int64_t AbsValue; 180 if (Value->evaluateAsAbsolute(AbsValue, getAssemblerPtr())) { 181 if (!isUIntN(8 * Size, AbsValue) && !isIntN(8 * Size, AbsValue)) { 182 getContext().reportError( 183 Loc, "value evaluated as " + Twine(AbsValue) + " is out of range."); 184 return; 185 } 186 EmitIntValue(AbsValue, Size); 187 return; 188 } 189 DF->getFixups().push_back( 190 MCFixup::create(DF->getContents().size(), Value, 191 MCFixup::getKindForSize(Size, false), Loc)); 192 DF->getContents().resize(DF->getContents().size() + Size, 0); 193 } 194 195 MCSymbol *MCObjectStreamer::EmitCFILabel() { 196 MCSymbol *Label = getContext().createTempSymbol("cfi", true); 197 EmitLabel(Label); 198 return Label; 199 } 200 201 void MCObjectStreamer::EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) { 202 // We need to create a local symbol to avoid relocations. 203 Frame.Begin = getContext().createTempSymbol(); 204 EmitLabel(Frame.Begin); 205 } 206 207 void MCObjectStreamer::EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) { 208 Frame.End = getContext().createTempSymbol(); 209 EmitLabel(Frame.End); 210 } 211 212 void MCObjectStreamer::EmitLabel(MCSymbol *Symbol, SMLoc Loc) { 213 MCStreamer::EmitLabel(Symbol, Loc); 214 215 getAssembler().registerSymbol(*Symbol); 216 217 // If there is a current fragment, mark the symbol as pointing into it. 218 // Otherwise queue the label and set its fragment pointer when we emit the 219 // next fragment. 220 auto *F = dyn_cast_or_null<MCDataFragment>(getCurrentFragment()); 221 if (F && !(getAssembler().isBundlingEnabled() && 222 getAssembler().getRelaxAll())) { 223 Symbol->setFragment(F); 224 Symbol->setOffset(F->getContents().size()); 225 } else { 226 PendingLabels.push_back(Symbol); 227 } 228 } 229 230 void MCObjectStreamer::EmitLabel(MCSymbol *Symbol, SMLoc Loc, MCFragment *F) { 231 MCStreamer::EmitLabel(Symbol, Loc); 232 getAssembler().registerSymbol(*Symbol); 233 auto *DF = dyn_cast_or_null<MCDataFragment>(F); 234 if (DF) 235 Symbol->setFragment(F); 236 else 237 PendingLabels.push_back(Symbol); 238 } 239 240 void MCObjectStreamer::EmitULEB128Value(const MCExpr *Value) { 241 int64_t IntValue; 242 if (Value->evaluateAsAbsolute(IntValue, getAssemblerPtr())) { 243 EmitULEB128IntValue(IntValue); 244 return; 245 } 246 insert(new MCLEBFragment(*Value, false)); 247 } 248 249 void MCObjectStreamer::EmitSLEB128Value(const MCExpr *Value) { 250 int64_t IntValue; 251 if (Value->evaluateAsAbsolute(IntValue, getAssemblerPtr())) { 252 EmitSLEB128IntValue(IntValue); 253 return; 254 } 255 insert(new MCLEBFragment(*Value, true)); 256 } 257 258 void MCObjectStreamer::EmitWeakReference(MCSymbol *Alias, 259 const MCSymbol *Symbol) { 260 report_fatal_error("This file format doesn't support weak aliases."); 261 } 262 263 void MCObjectStreamer::ChangeSection(MCSection *Section, 264 const MCExpr *Subsection) { 265 changeSectionImpl(Section, Subsection); 266 } 267 268 bool MCObjectStreamer::changeSectionImpl(MCSection *Section, 269 const MCExpr *Subsection) { 270 assert(Section && "Cannot switch to a null section!"); 271 flushPendingLabels(nullptr); 272 getContext().clearDwarfLocSeen(); 273 274 bool Created = getAssembler().registerSection(*Section); 275 276 int64_t IntSubsection = 0; 277 if (Subsection && 278 !Subsection->evaluateAsAbsolute(IntSubsection, getAssemblerPtr())) 279 report_fatal_error("Cannot evaluate subsection number"); 280 if (IntSubsection < 0 || IntSubsection > 8192) 281 report_fatal_error("Subsection number out of range"); 282 CurInsertionPoint = 283 Section->getSubsectionInsertionPoint(unsigned(IntSubsection)); 284 return Created; 285 } 286 287 void MCObjectStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) { 288 getAssembler().registerSymbol(*Symbol); 289 MCStreamer::EmitAssignment(Symbol, Value); 290 } 291 292 bool MCObjectStreamer::mayHaveInstructions(MCSection &Sec) const { 293 return Sec.hasInstructions(); 294 } 295 296 void MCObjectStreamer::EmitInstruction(const MCInst &Inst, 297 const MCSubtargetInfo &STI, bool) { 298 getAssembler().getBackend().handleCodePaddingInstructionBegin(Inst); 299 EmitInstructionImpl(Inst, STI); 300 getAssembler().getBackend().handleCodePaddingInstructionEnd(Inst); 301 } 302 303 void MCObjectStreamer::EmitInstructionImpl(const MCInst &Inst, 304 const MCSubtargetInfo &STI) { 305 MCStreamer::EmitInstruction(Inst, STI); 306 307 MCSection *Sec = getCurrentSectionOnly(); 308 Sec->setHasInstructions(true); 309 310 // Now that a machine instruction has been assembled into this section, make 311 // a line entry for any .loc directive that has been seen. 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 // Validate the directive. 447 if (!checkCVLocSection(FunctionId, FileNo, Loc)) 448 return; 449 450 // Emit a label at the current position and record it in the CodeViewContext. 451 MCSymbol *LineSym = getContext().createTempSymbol(); 452 EmitLabel(LineSym); 453 getContext().getCVContext().recordCVLoc(getContext(), LineSym, FunctionId, 454 FileNo, Line, Column, PrologueEnd, 455 IsStmt); 456 } 457 458 void MCObjectStreamer::EmitCVLinetableDirective(unsigned FunctionId, 459 const MCSymbol *Begin, 460 const MCSymbol *End) { 461 getContext().getCVContext().emitLineTableForFunction(*this, FunctionId, Begin, 462 End); 463 this->MCStreamer::EmitCVLinetableDirective(FunctionId, Begin, End); 464 } 465 466 void MCObjectStreamer::EmitCVInlineLinetableDirective( 467 unsigned PrimaryFunctionId, unsigned SourceFileId, unsigned SourceLineNum, 468 const MCSymbol *FnStartSym, const MCSymbol *FnEndSym) { 469 getContext().getCVContext().emitInlineLineTableForFunction( 470 *this, PrimaryFunctionId, SourceFileId, SourceLineNum, FnStartSym, 471 FnEndSym); 472 this->MCStreamer::EmitCVInlineLinetableDirective( 473 PrimaryFunctionId, SourceFileId, SourceLineNum, FnStartSym, FnEndSym); 474 } 475 476 void MCObjectStreamer::EmitCVDefRangeDirective( 477 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges, 478 StringRef FixedSizePortion) { 479 getContext().getCVContext().emitDefRange(*this, Ranges, FixedSizePortion); 480 this->MCStreamer::EmitCVDefRangeDirective(Ranges, FixedSizePortion); 481 } 482 483 void MCObjectStreamer::EmitCVStringTableDirective() { 484 getContext().getCVContext().emitStringTable(*this); 485 } 486 void MCObjectStreamer::EmitCVFileChecksumsDirective() { 487 getContext().getCVContext().emitFileChecksums(*this); 488 } 489 490 void MCObjectStreamer::EmitCVFileChecksumOffsetDirective(unsigned FileNo) { 491 getContext().getCVContext().emitFileChecksumOffset(*this, FileNo); 492 } 493 494 void MCObjectStreamer::EmitBytes(StringRef Data) { 495 MCDwarfLineEntry::Make(this, getCurrentSectionOnly()); 496 MCDataFragment *DF = getOrCreateDataFragment(); 497 flushPendingLabels(DF, DF->getContents().size()); 498 DF->getContents().append(Data.begin(), Data.end()); 499 500 // EmitBytes might not cover all possible ways we emit data (or could be used 501 // to emit executable code in some cases), but is the best method we have 502 // right now for checking this. 503 MCSection *Sec = getCurrentSectionOnly(); 504 Sec->setHasData(true); 505 } 506 507 void MCObjectStreamer::EmitValueToAlignment(unsigned ByteAlignment, 508 int64_t Value, 509 unsigned ValueSize, 510 unsigned MaxBytesToEmit) { 511 if (MaxBytesToEmit == 0) 512 MaxBytesToEmit = ByteAlignment; 513 insert(new MCAlignFragment(ByteAlignment, Value, ValueSize, MaxBytesToEmit)); 514 515 // Update the maximum alignment on the current section if necessary. 516 MCSection *CurSec = getCurrentSectionOnly(); 517 if (ByteAlignment > CurSec->getAlignment()) 518 CurSec->setAlignment(ByteAlignment); 519 } 520 521 void MCObjectStreamer::EmitCodeAlignment(unsigned ByteAlignment, 522 unsigned MaxBytesToEmit) { 523 EmitValueToAlignment(ByteAlignment, 0, 1, MaxBytesToEmit); 524 cast<MCAlignFragment>(getCurrentFragment())->setEmitNops(true); 525 } 526 527 void MCObjectStreamer::emitValueToOffset(const MCExpr *Offset, 528 unsigned char Value, 529 SMLoc Loc) { 530 insert(new MCOrgFragment(*Offset, Value, Loc)); 531 } 532 533 void MCObjectStreamer::EmitCodePaddingBasicBlockStart( 534 const MCCodePaddingContext &Context) { 535 getAssembler().getBackend().handleCodePaddingBasicBlockStart(this, Context); 536 } 537 538 void MCObjectStreamer::EmitCodePaddingBasicBlockEnd( 539 const MCCodePaddingContext &Context) { 540 getAssembler().getBackend().handleCodePaddingBasicBlockEnd(Context); 541 } 542 543 // Associate DTPRel32 fixup with data and resize data area 544 void MCObjectStreamer::EmitDTPRel32Value(const MCExpr *Value) { 545 MCDataFragment *DF = getOrCreateDataFragment(); 546 flushPendingLabels(DF, DF->getContents().size()); 547 548 DF->getFixups().push_back(MCFixup::create(DF->getContents().size(), 549 Value, FK_DTPRel_4)); 550 DF->getContents().resize(DF->getContents().size() + 4, 0); 551 } 552 553 // Associate DTPRel64 fixup with data and resize data area 554 void MCObjectStreamer::EmitDTPRel64Value(const MCExpr *Value) { 555 MCDataFragment *DF = getOrCreateDataFragment(); 556 flushPendingLabels(DF, DF->getContents().size()); 557 558 DF->getFixups().push_back(MCFixup::create(DF->getContents().size(), 559 Value, FK_DTPRel_8)); 560 DF->getContents().resize(DF->getContents().size() + 8, 0); 561 } 562 563 // Associate TPRel32 fixup with data and resize data area 564 void MCObjectStreamer::EmitTPRel32Value(const MCExpr *Value) { 565 MCDataFragment *DF = getOrCreateDataFragment(); 566 flushPendingLabels(DF, DF->getContents().size()); 567 568 DF->getFixups().push_back(MCFixup::create(DF->getContents().size(), 569 Value, FK_TPRel_4)); 570 DF->getContents().resize(DF->getContents().size() + 4, 0); 571 } 572 573 // Associate TPRel64 fixup with data and resize data area 574 void MCObjectStreamer::EmitTPRel64Value(const MCExpr *Value) { 575 MCDataFragment *DF = getOrCreateDataFragment(); 576 flushPendingLabels(DF, DF->getContents().size()); 577 578 DF->getFixups().push_back(MCFixup::create(DF->getContents().size(), 579 Value, FK_TPRel_8)); 580 DF->getContents().resize(DF->getContents().size() + 8, 0); 581 } 582 583 // Associate GPRel32 fixup with data and resize data area 584 void MCObjectStreamer::EmitGPRel32Value(const MCExpr *Value) { 585 MCDataFragment *DF = getOrCreateDataFragment(); 586 flushPendingLabels(DF, DF->getContents().size()); 587 588 DF->getFixups().push_back( 589 MCFixup::create(DF->getContents().size(), Value, FK_GPRel_4)); 590 DF->getContents().resize(DF->getContents().size() + 4, 0); 591 } 592 593 // Associate GPRel64 fixup with data and resize data area 594 void MCObjectStreamer::EmitGPRel64Value(const MCExpr *Value) { 595 MCDataFragment *DF = getOrCreateDataFragment(); 596 flushPendingLabels(DF, DF->getContents().size()); 597 598 DF->getFixups().push_back( 599 MCFixup::create(DF->getContents().size(), Value, FK_GPRel_4)); 600 DF->getContents().resize(DF->getContents().size() + 8, 0); 601 } 602 603 bool MCObjectStreamer::EmitRelocDirective(const MCExpr &Offset, StringRef Name, 604 const MCExpr *Expr, SMLoc Loc, 605 const MCSubtargetInfo &STI) { 606 int64_t OffsetValue; 607 if (!Offset.evaluateAsAbsolute(OffsetValue)) 608 llvm_unreachable("Offset is not absolute"); 609 610 if (OffsetValue < 0) 611 llvm_unreachable("Offset is negative"); 612 613 MCDataFragment *DF = getOrCreateDataFragment(&STI); 614 flushPendingLabels(DF, DF->getContents().size()); 615 616 Optional<MCFixupKind> MaybeKind = Assembler->getBackend().getFixupKind(Name); 617 if (!MaybeKind.hasValue()) 618 return true; 619 620 MCFixupKind Kind = *MaybeKind; 621 622 if (Expr == nullptr) 623 Expr = 624 MCSymbolRefExpr::create(getContext().createTempSymbol(), getContext()); 625 DF->getFixups().push_back(MCFixup::create(OffsetValue, Expr, Kind, Loc)); 626 return false; 627 } 628 629 void MCObjectStreamer::emitFill(const MCExpr &NumBytes, uint64_t FillValue, 630 SMLoc Loc) { 631 MCDataFragment *DF = getOrCreateDataFragment(); 632 flushPendingLabels(DF, DF->getContents().size()); 633 634 assert(getCurrentSectionOnly() && "need a section"); 635 insert(new MCFillFragment(FillValue, 1, NumBytes, Loc)); 636 } 637 638 void MCObjectStreamer::emitFill(const MCExpr &NumValues, int64_t Size, 639 int64_t Expr, SMLoc Loc) { 640 int64_t IntNumValues; 641 // Do additional checking now if we can resolve the value. 642 if (NumValues.evaluateAsAbsolute(IntNumValues, getAssemblerPtr())) { 643 if (IntNumValues < 0) { 644 getContext().getSourceManager()->PrintMessage( 645 Loc, SourceMgr::DK_Warning, 646 "'.fill' directive with negative repeat count has no effect"); 647 return; 648 } 649 // Emit now if we can for better errors. 650 int64_t NonZeroSize = Size > 4 ? 4 : Size; 651 Expr &= ~0ULL >> (64 - NonZeroSize * 8); 652 for (uint64_t i = 0, e = IntNumValues; i != e; ++i) { 653 EmitIntValue(Expr, NonZeroSize); 654 if (NonZeroSize < Size) 655 EmitIntValue(0, Size - NonZeroSize); 656 } 657 return; 658 } 659 660 // Otherwise emit as fragment. 661 MCDataFragment *DF = getOrCreateDataFragment(); 662 flushPendingLabels(DF, DF->getContents().size()); 663 664 assert(getCurrentSectionOnly() && "need a section"); 665 insert(new MCFillFragment(Expr, Size, NumValues, Loc)); 666 } 667 668 void MCObjectStreamer::EmitFileDirective(StringRef Filename) { 669 getAssembler().addFileName(Filename); 670 } 671 672 void MCObjectStreamer::EmitAddrsig() { 673 getAssembler().getWriter().emitAddrsigSection(); 674 } 675 676 void MCObjectStreamer::EmitAddrsigSym(const MCSymbol *Sym) { 677 getAssembler().registerSymbol(*Sym); 678 getAssembler().getWriter().addAddrsigSymbol(Sym); 679 } 680 681 void MCObjectStreamer::FinishImpl() { 682 getContext().RemapDebugPaths(); 683 684 // If we are generating dwarf for assembly source files dump out the sections. 685 if (getContext().getGenDwarfForAssembly()) 686 MCGenDwarfInfo::Emit(this); 687 688 // Dump out the dwarf file & directory tables and line tables. 689 MCDwarfLineTable::Emit(this, getAssembler().getDWARFLinetableParams()); 690 691 flushPendingLabels(); 692 getAssembler().Finish(); 693 } 694