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