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