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 430 void MCObjectStreamer::EmitBytes(StringRef Data) { 431 MCCVLineEntry::Make(this); 432 MCDwarfLineEntry::Make(this, getCurrentSectionOnly()); 433 MCDataFragment *DF = getOrCreateDataFragment(); 434 flushPendingLabels(DF, DF->getContents().size()); 435 DF->getContents().append(Data.begin(), Data.end()); 436 } 437 438 void MCObjectStreamer::EmitValueToAlignment(unsigned ByteAlignment, 439 int64_t Value, 440 unsigned ValueSize, 441 unsigned MaxBytesToEmit) { 442 if (MaxBytesToEmit == 0) 443 MaxBytesToEmit = ByteAlignment; 444 insert(new MCAlignFragment(ByteAlignment, Value, ValueSize, MaxBytesToEmit)); 445 446 // Update the maximum alignment on the current section if necessary. 447 MCSection *CurSec = getCurrentSectionOnly(); 448 if (ByteAlignment > CurSec->getAlignment()) 449 CurSec->setAlignment(ByteAlignment); 450 } 451 452 void MCObjectStreamer::EmitCodeAlignment(unsigned ByteAlignment, 453 unsigned MaxBytesToEmit) { 454 EmitValueToAlignment(ByteAlignment, 0, 1, MaxBytesToEmit); 455 cast<MCAlignFragment>(getCurrentFragment())->setEmitNops(true); 456 } 457 458 void MCObjectStreamer::emitValueToOffset(const MCExpr *Offset, 459 unsigned char Value, 460 SMLoc Loc) { 461 insert(new MCOrgFragment(*Offset, Value, Loc)); 462 } 463 464 // Associate DTPRel32 fixup with data and resize data area 465 void MCObjectStreamer::EmitDTPRel32Value(const MCExpr *Value) { 466 MCDataFragment *DF = getOrCreateDataFragment(); 467 flushPendingLabels(DF, DF->getContents().size()); 468 469 DF->getFixups().push_back(MCFixup::create(DF->getContents().size(), 470 Value, FK_DTPRel_4)); 471 DF->getContents().resize(DF->getContents().size() + 4, 0); 472 } 473 474 // Associate DTPRel64 fixup with data and resize data area 475 void MCObjectStreamer::EmitDTPRel64Value(const MCExpr *Value) { 476 MCDataFragment *DF = getOrCreateDataFragment(); 477 flushPendingLabels(DF, DF->getContents().size()); 478 479 DF->getFixups().push_back(MCFixup::create(DF->getContents().size(), 480 Value, FK_DTPRel_8)); 481 DF->getContents().resize(DF->getContents().size() + 8, 0); 482 } 483 484 // Associate TPRel32 fixup with data and resize data area 485 void MCObjectStreamer::EmitTPRel32Value(const MCExpr *Value) { 486 MCDataFragment *DF = getOrCreateDataFragment(); 487 flushPendingLabels(DF, DF->getContents().size()); 488 489 DF->getFixups().push_back(MCFixup::create(DF->getContents().size(), 490 Value, FK_TPRel_4)); 491 DF->getContents().resize(DF->getContents().size() + 4, 0); 492 } 493 494 // Associate TPRel64 fixup with data and resize data area 495 void MCObjectStreamer::EmitTPRel64Value(const MCExpr *Value) { 496 MCDataFragment *DF = getOrCreateDataFragment(); 497 flushPendingLabels(DF, DF->getContents().size()); 498 499 DF->getFixups().push_back(MCFixup::create(DF->getContents().size(), 500 Value, FK_TPRel_8)); 501 DF->getContents().resize(DF->getContents().size() + 8, 0); 502 } 503 504 // Associate GPRel32 fixup with data and resize data area 505 void MCObjectStreamer::EmitGPRel32Value(const MCExpr *Value) { 506 MCDataFragment *DF = getOrCreateDataFragment(); 507 flushPendingLabels(DF, DF->getContents().size()); 508 509 DF->getFixups().push_back( 510 MCFixup::create(DF->getContents().size(), Value, FK_GPRel_4)); 511 DF->getContents().resize(DF->getContents().size() + 4, 0); 512 } 513 514 // Associate GPRel64 fixup with data and resize data area 515 void MCObjectStreamer::EmitGPRel64Value(const MCExpr *Value) { 516 MCDataFragment *DF = getOrCreateDataFragment(); 517 flushPendingLabels(DF, DF->getContents().size()); 518 519 DF->getFixups().push_back( 520 MCFixup::create(DF->getContents().size(), Value, FK_GPRel_4)); 521 DF->getContents().resize(DF->getContents().size() + 8, 0); 522 } 523 524 bool MCObjectStreamer::EmitRelocDirective(const MCExpr &Offset, StringRef Name, 525 const MCExpr *Expr, SMLoc Loc) { 526 int64_t OffsetValue; 527 if (!Offset.evaluateAsAbsolute(OffsetValue)) 528 llvm_unreachable("Offset is not absolute"); 529 530 if (OffsetValue < 0) 531 llvm_unreachable("Offset is negative"); 532 533 MCDataFragment *DF = getOrCreateDataFragment(); 534 flushPendingLabels(DF, DF->getContents().size()); 535 536 Optional<MCFixupKind> MaybeKind = Assembler->getBackend().getFixupKind(Name); 537 if (!MaybeKind.hasValue()) 538 return true; 539 540 MCFixupKind Kind = *MaybeKind; 541 542 if (Expr == nullptr) 543 Expr = 544 MCSymbolRefExpr::create(getContext().createTempSymbol(), getContext()); 545 DF->getFixups().push_back(MCFixup::create(OffsetValue, Expr, Kind, Loc)); 546 return false; 547 } 548 549 void MCObjectStreamer::emitFill(uint64_t NumBytes, uint8_t FillValue) { 550 assert(getCurrentSectionOnly() && "need a section"); 551 insert(new MCFillFragment(FillValue, NumBytes)); 552 } 553 554 void MCObjectStreamer::emitFill(const MCExpr &NumBytes, uint64_t FillValue, 555 SMLoc Loc) { 556 MCDataFragment *DF = getOrCreateDataFragment(); 557 flushPendingLabels(DF, DF->getContents().size()); 558 559 int64_t IntNumBytes; 560 if (!NumBytes.evaluateAsAbsolute(IntNumBytes, getAssembler())) { 561 getContext().reportError(Loc, "expected absolute expression"); 562 return; 563 } 564 565 if (IntNumBytes <= 0) { 566 getContext().reportError(Loc, "invalid number of bytes"); 567 return; 568 } 569 570 emitFill(IntNumBytes, FillValue); 571 } 572 573 void MCObjectStreamer::emitFill(const MCExpr &NumValues, int64_t Size, 574 int64_t Expr, SMLoc Loc) { 575 int64_t IntNumValues; 576 if (!NumValues.evaluateAsAbsolute(IntNumValues, getAssembler())) { 577 getContext().reportError(Loc, "expected absolute expression"); 578 return; 579 } 580 581 if (IntNumValues < 0) { 582 getContext().getSourceManager()->PrintMessage( 583 Loc, SourceMgr::DK_Warning, 584 "'.fill' directive with negative repeat count has no effect"); 585 return; 586 } 587 588 MCStreamer::emitFill(IntNumValues, Size, Expr); 589 } 590 591 void MCObjectStreamer::EmitFileDirective(StringRef Filename) { 592 getAssembler().addFileName(Filename); 593 } 594 595 void MCObjectStreamer::FinishImpl() { 596 // If we are generating dwarf for assembly source files dump out the sections. 597 if (getContext().getGenDwarfForAssembly()) 598 MCGenDwarfInfo::Emit(this); 599 600 // Dump out the dwarf file & directory tables and line tables. 601 MCDwarfLineTable::Emit(this, getAssembler().getDWARFLinetableParams()); 602 603 flushPendingLabels(nullptr); 604 getAssembler().Finish(); 605 } 606