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