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