1 //===- MCAssembler.h - Object File Generation -------------------*- C++ -*-===// 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 #ifndef LLVM_MC_MCASSEMBLER_H 11 #define LLVM_MC_MCASSEMBLER_H 12 13 #include "llvm/ADT/SmallPtrSet.h" 14 #include "llvm/ADT/ilist.h" 15 #include "llvm/ADT/ilist_node.h" 16 #include "llvm/ADT/iterator.h" 17 #include "llvm/MC/MCDirectives.h" 18 #include "llvm/MC/MCDwarf.h" 19 #include "llvm/MC/MCFixup.h" 20 #include "llvm/MC/MCInst.h" 21 #include "llvm/MC/MCLinkerOptimizationHint.h" 22 #include "llvm/MC/MCSubtargetInfo.h" 23 24 namespace llvm { 25 class raw_ostream; 26 class MCAsmLayout; 27 class MCAssembler; 28 class MCContext; 29 class MCCodeEmitter; 30 class MCExpr; 31 class MCFragment; 32 class MCObjectWriter; 33 class MCSection; 34 class MCSubtargetInfo; 35 class MCValue; 36 class MCAsmBackend; 37 38 class MCFragment : public ilist_node_with_parent<MCFragment, MCSection> { 39 friend class MCAsmLayout; 40 41 MCFragment(const MCFragment &) = delete; 42 void operator=(const MCFragment &) = delete; 43 44 public: 45 enum FragmentType : uint8_t { 46 FT_Align, 47 FT_Data, 48 FT_CompactEncodedInst, 49 FT_Fill, 50 FT_Relaxable, 51 FT_Org, 52 FT_Dwarf, 53 FT_DwarfFrame, 54 FT_LEB, 55 FT_SafeSEH, 56 FT_Dummy 57 }; 58 59 private: 60 FragmentType Kind; 61 62 protected: 63 bool HasInstructions; 64 65 private: 66 /// \brief Should this fragment be aligned to the end of a bundle? 67 bool AlignToBundleEnd; 68 69 uint8_t BundlePadding; 70 71 /// LayoutOrder - The layout order of this fragment. 72 unsigned LayoutOrder; 73 74 /// The data for the section this fragment is in. 75 MCSection *Parent; 76 77 /// Atom - The atom this fragment is in, as represented by it's defining 78 /// symbol. 79 const MCSymbol *Atom; 80 81 /// \name Assembler Backend Data 82 /// @{ 83 // 84 // FIXME: This could all be kept private to the assembler implementation. 85 86 /// Offset - The offset of this fragment in its section. This is ~0 until 87 /// initialized. 88 uint64_t Offset; 89 90 /// @} 91 92 protected: 93 MCFragment(FragmentType Kind, bool HasInstructions, 94 uint8_t BundlePadding, MCSection *Parent = nullptr); 95 96 ~MCFragment(); 97 private: 98 99 // This is a friend so that the sentinal can be created. 100 friend struct ilist_sentinel_traits<MCFragment>; 101 MCFragment(); 102 103 public: 104 /// Destroys the current fragment. 105 /// 106 /// This must be used instead of delete as MCFragment is non-virtual. 107 /// This method will dispatch to the appropriate subclass. 108 void destroy(); 109 110 FragmentType getKind() const { return Kind; } 111 112 MCSection *getParent() const { return Parent; } 113 void setParent(MCSection *Value) { Parent = Value; } 114 115 const MCSymbol *getAtom() const { return Atom; } 116 void setAtom(const MCSymbol *Value) { Atom = Value; } 117 118 unsigned getLayoutOrder() const { return LayoutOrder; } 119 void setLayoutOrder(unsigned Value) { LayoutOrder = Value; } 120 121 /// \brief Does this fragment have instructions emitted into it? By default 122 /// this is false, but specific fragment types may set it to true. 123 bool hasInstructions() const { return HasInstructions; } 124 125 /// \brief Should this fragment be placed at the end of an aligned bundle? 126 bool alignToBundleEnd() const { return AlignToBundleEnd; } 127 void setAlignToBundleEnd(bool V) { AlignToBundleEnd = V; } 128 129 /// \brief Get the padding size that must be inserted before this fragment. 130 /// Used for bundling. By default, no padding is inserted. 131 /// Note that padding size is restricted to 8 bits. This is an optimization 132 /// to reduce the amount of space used for each fragment. In practice, larger 133 /// padding should never be required. 134 uint8_t getBundlePadding() const { return BundlePadding; } 135 136 /// \brief Set the padding size for this fragment. By default it's a no-op, 137 /// and only some fragments have a meaningful implementation. 138 void setBundlePadding(uint8_t N) { BundlePadding = N; } 139 140 /// \brief Return true if given frgment has FT_Dummy type. 141 bool isDummy() const { return Kind == FT_Dummy; } 142 143 void dump(); 144 }; 145 146 class MCDummyFragment : public MCFragment { 147 public: 148 explicit MCDummyFragment(MCSection *Sec) 149 : MCFragment(FT_Dummy, false, 0, Sec){}; 150 static bool classof(const MCFragment *F) { return F->getKind() == FT_Dummy; } 151 }; 152 153 /// Interface implemented by fragments that contain encoded instructions and/or 154 /// data. 155 /// 156 class MCEncodedFragment : public MCFragment { 157 protected: 158 MCEncodedFragment(MCFragment::FragmentType FType, bool HasInstructions, 159 MCSection *Sec) 160 : MCFragment(FType, HasInstructions, 0, Sec) {} 161 162 public: 163 static bool classof(const MCFragment *F) { 164 MCFragment::FragmentType Kind = F->getKind(); 165 switch (Kind) { 166 default: 167 return false; 168 case MCFragment::FT_Relaxable: 169 case MCFragment::FT_CompactEncodedInst: 170 case MCFragment::FT_Data: 171 return true; 172 } 173 } 174 }; 175 176 /// Interface implemented by fragments that contain encoded instructions and/or 177 /// data. 178 /// 179 template<unsigned ContentsSize> 180 class MCEncodedFragmentWithContents : public MCEncodedFragment { 181 SmallVector<char, ContentsSize> Contents; 182 183 protected: 184 MCEncodedFragmentWithContents(MCFragment::FragmentType FType, 185 bool HasInstructions, 186 MCSection *Sec) 187 : MCEncodedFragment(FType, HasInstructions, Sec) {} 188 189 public: 190 SmallVectorImpl<char> &getContents() { return Contents; } 191 const SmallVectorImpl<char> &getContents() const { return Contents; } 192 }; 193 194 /// Interface implemented by fragments that contain encoded instructions and/or 195 /// data and also have fixups registered. 196 /// 197 template<unsigned ContentsSize, unsigned FixupsSize> 198 class MCEncodedFragmentWithFixups : 199 public MCEncodedFragmentWithContents<ContentsSize> { 200 201 /// Fixups - The list of fixups in this fragment. 202 SmallVector<MCFixup, FixupsSize> Fixups; 203 204 protected: 205 MCEncodedFragmentWithFixups(MCFragment::FragmentType FType, 206 bool HasInstructions, 207 MCSection *Sec) 208 : MCEncodedFragmentWithContents<ContentsSize>(FType, HasInstructions, 209 Sec) {} 210 211 public: 212 typedef SmallVectorImpl<MCFixup>::const_iterator const_fixup_iterator; 213 typedef SmallVectorImpl<MCFixup>::iterator fixup_iterator; 214 215 SmallVectorImpl<MCFixup> &getFixups() { return Fixups; } 216 const SmallVectorImpl<MCFixup> &getFixups() const { return Fixups; } 217 218 fixup_iterator fixup_begin() { return Fixups.begin(); } 219 const_fixup_iterator fixup_begin() const { return Fixups.begin(); } 220 221 fixup_iterator fixup_end() { return Fixups.end(); } 222 const_fixup_iterator fixup_end() const { return Fixups.end(); } 223 224 static bool classof(const MCFragment *F) { 225 MCFragment::FragmentType Kind = F->getKind(); 226 return Kind == MCFragment::FT_Relaxable || Kind == MCFragment::FT_Data; 227 } 228 }; 229 230 /// Fragment for data and encoded instructions. 231 /// 232 class MCDataFragment : public MCEncodedFragmentWithFixups<32, 4> { 233 public: 234 MCDataFragment(MCSection *Sec = nullptr) 235 : MCEncodedFragmentWithFixups<32, 4>(FT_Data, false, Sec) {} 236 237 void setHasInstructions(bool V) { HasInstructions = V; } 238 239 static bool classof(const MCFragment *F) { 240 return F->getKind() == MCFragment::FT_Data; 241 } 242 }; 243 244 /// This is a compact (memory-size-wise) fragment for holding an encoded 245 /// instruction (non-relaxable) that has no fixups registered. When applicable, 246 /// it can be used instead of MCDataFragment and lead to lower memory 247 /// consumption. 248 /// 249 class MCCompactEncodedInstFragment : public MCEncodedFragmentWithContents<4> { 250 public: 251 MCCompactEncodedInstFragment(MCSection *Sec = nullptr) 252 : MCEncodedFragmentWithContents(FT_CompactEncodedInst, true, Sec) { 253 } 254 255 static bool classof(const MCFragment *F) { 256 return F->getKind() == MCFragment::FT_CompactEncodedInst; 257 } 258 }; 259 260 /// A relaxable fragment holds on to its MCInst, since it may need to be 261 /// relaxed during the assembler layout and relaxation stage. 262 /// 263 class MCRelaxableFragment : public MCEncodedFragmentWithFixups<8, 1> { 264 265 /// Inst - The instruction this is a fragment for. 266 MCInst Inst; 267 268 /// STI - The MCSubtargetInfo in effect when the instruction was encoded. 269 const MCSubtargetInfo &STI; 270 271 public: 272 MCRelaxableFragment(const MCInst &Inst, const MCSubtargetInfo &STI, 273 MCSection *Sec = nullptr) 274 : MCEncodedFragmentWithFixups(FT_Relaxable, true, Sec), 275 Inst(Inst), STI(STI) {} 276 277 const MCInst &getInst() const { return Inst; } 278 void setInst(const MCInst &Value) { Inst = Value; } 279 280 const MCSubtargetInfo &getSubtargetInfo() { return STI; } 281 282 static bool classof(const MCFragment *F) { 283 return F->getKind() == MCFragment::FT_Relaxable; 284 } 285 }; 286 287 class MCAlignFragment : public MCFragment { 288 289 /// Alignment - The alignment to ensure, in bytes. 290 unsigned Alignment; 291 292 /// EmitNops - Flag to indicate that (optimal) NOPs should be emitted instead 293 /// of using the provided value. The exact interpretation of this flag is 294 /// target dependent. 295 bool EmitNops : 1; 296 297 /// Value - Value to use for filling padding bytes. 298 int64_t Value; 299 300 /// ValueSize - The size of the integer (in bytes) of \p Value. 301 unsigned ValueSize; 302 303 /// MaxBytesToEmit - The maximum number of bytes to emit; if the alignment 304 /// cannot be satisfied in this width then this fragment is ignored. 305 unsigned MaxBytesToEmit; 306 307 public: 308 MCAlignFragment(unsigned Alignment, int64_t Value, unsigned ValueSize, 309 unsigned MaxBytesToEmit, MCSection *Sec = nullptr) 310 : MCFragment(FT_Align, false, 0, Sec), Alignment(Alignment), 311 EmitNops(false), Value(Value), 312 ValueSize(ValueSize), MaxBytesToEmit(MaxBytesToEmit) {} 313 314 /// \name Accessors 315 /// @{ 316 317 unsigned getAlignment() const { return Alignment; } 318 319 int64_t getValue() const { return Value; } 320 321 unsigned getValueSize() const { return ValueSize; } 322 323 unsigned getMaxBytesToEmit() const { return MaxBytesToEmit; } 324 325 bool hasEmitNops() const { return EmitNops; } 326 void setEmitNops(bool Value) { EmitNops = Value; } 327 328 /// @} 329 330 static bool classof(const MCFragment *F) { 331 return F->getKind() == MCFragment::FT_Align; 332 } 333 }; 334 335 class MCFillFragment : public MCFragment { 336 337 /// Value - Value to use for filling bytes. 338 int64_t Value; 339 340 /// ValueSize - The size (in bytes) of \p Value to use when filling, or 0 if 341 /// this is a virtual fill fragment. 342 unsigned ValueSize; 343 344 /// Size - The number of bytes to insert. 345 uint64_t Size; 346 347 public: 348 MCFillFragment(int64_t Value, unsigned ValueSize, uint64_t Size, 349 MCSection *Sec = nullptr) 350 : MCFragment(FT_Fill, false, 0, Sec), Value(Value), ValueSize(ValueSize), 351 Size(Size) { 352 assert((!ValueSize || (Size % ValueSize) == 0) && 353 "Fill size must be a multiple of the value size!"); 354 } 355 356 /// \name Accessors 357 /// @{ 358 359 int64_t getValue() const { return Value; } 360 361 unsigned getValueSize() const { return ValueSize; } 362 363 uint64_t getSize() const { return Size; } 364 365 /// @} 366 367 static bool classof(const MCFragment *F) { 368 return F->getKind() == MCFragment::FT_Fill; 369 } 370 }; 371 372 class MCOrgFragment : public MCFragment { 373 374 /// Offset - The offset this fragment should start at. 375 const MCExpr *Offset; 376 377 /// Value - Value to use for filling bytes. 378 int8_t Value; 379 380 public: 381 MCOrgFragment(const MCExpr &Offset, int8_t Value, MCSection *Sec = nullptr) 382 : MCFragment(FT_Org, false, 0, Sec), Offset(&Offset), Value(Value) {} 383 384 /// \name Accessors 385 /// @{ 386 387 const MCExpr &getOffset() const { return *Offset; } 388 389 uint8_t getValue() const { return Value; } 390 391 /// @} 392 393 static bool classof(const MCFragment *F) { 394 return F->getKind() == MCFragment::FT_Org; 395 } 396 }; 397 398 class MCLEBFragment : public MCFragment { 399 400 /// Value - The value this fragment should contain. 401 const MCExpr *Value; 402 403 /// IsSigned - True if this is a sleb128, false if uleb128. 404 bool IsSigned; 405 406 SmallString<8> Contents; 407 408 public: 409 MCLEBFragment(const MCExpr &Value_, bool IsSigned_, MCSection *Sec = nullptr) 410 : MCFragment(FT_LEB, false, 0, Sec), Value(&Value_), IsSigned(IsSigned_) { 411 Contents.push_back(0); 412 } 413 414 /// \name Accessors 415 /// @{ 416 417 const MCExpr &getValue() const { return *Value; } 418 419 bool isSigned() const { return IsSigned; } 420 421 SmallString<8> &getContents() { return Contents; } 422 const SmallString<8> &getContents() const { return Contents; } 423 424 /// @} 425 426 static bool classof(const MCFragment *F) { 427 return F->getKind() == MCFragment::FT_LEB; 428 } 429 }; 430 431 class MCDwarfLineAddrFragment : public MCFragment { 432 433 /// LineDelta - the value of the difference between the two line numbers 434 /// between two .loc dwarf directives. 435 int64_t LineDelta; 436 437 /// AddrDelta - The expression for the difference of the two symbols that 438 /// make up the address delta between two .loc dwarf directives. 439 const MCExpr *AddrDelta; 440 441 SmallString<8> Contents; 442 443 public: 444 MCDwarfLineAddrFragment(int64_t LineDelta, const MCExpr &AddrDelta, 445 MCSection *Sec = nullptr) 446 : MCFragment(FT_Dwarf, false, 0, Sec), LineDelta(LineDelta), 447 AddrDelta(&AddrDelta) { 448 Contents.push_back(0); 449 } 450 451 /// \name Accessors 452 /// @{ 453 454 int64_t getLineDelta() const { return LineDelta; } 455 456 const MCExpr &getAddrDelta() const { return *AddrDelta; } 457 458 SmallString<8> &getContents() { return Contents; } 459 const SmallString<8> &getContents() const { return Contents; } 460 461 /// @} 462 463 static bool classof(const MCFragment *F) { 464 return F->getKind() == MCFragment::FT_Dwarf; 465 } 466 }; 467 468 class MCDwarfCallFrameFragment : public MCFragment { 469 470 /// AddrDelta - The expression for the difference of the two symbols that 471 /// make up the address delta between two .cfi_* dwarf directives. 472 const MCExpr *AddrDelta; 473 474 SmallString<8> Contents; 475 476 public: 477 MCDwarfCallFrameFragment(const MCExpr &AddrDelta, MCSection *Sec = nullptr) 478 : MCFragment(FT_DwarfFrame, false, 0, Sec), AddrDelta(&AddrDelta) { 479 Contents.push_back(0); 480 } 481 482 /// \name Accessors 483 /// @{ 484 485 const MCExpr &getAddrDelta() const { return *AddrDelta; } 486 487 SmallString<8> &getContents() { return Contents; } 488 const SmallString<8> &getContents() const { return Contents; } 489 490 /// @} 491 492 static bool classof(const MCFragment *F) { 493 return F->getKind() == MCFragment::FT_DwarfFrame; 494 } 495 }; 496 497 class MCSafeSEHFragment : public MCFragment { 498 const MCSymbol *Sym; 499 500 public: 501 MCSafeSEHFragment(const MCSymbol *Sym, MCSection *Sec = nullptr) 502 : MCFragment(FT_SafeSEH, false, 0, Sec), Sym(Sym) {} 503 504 /// \name Accessors 505 /// @{ 506 507 const MCSymbol *getSymbol() { return Sym; } 508 const MCSymbol *getSymbol() const { return Sym; } 509 510 /// @} 511 512 static bool classof(const MCFragment *F) { 513 return F->getKind() == MCFragment::FT_SafeSEH; 514 } 515 }; 516 517 // FIXME: This really doesn't belong here. See comments below. 518 struct IndirectSymbolData { 519 MCSymbol *Symbol; 520 MCSection *Section; 521 }; 522 523 // FIXME: Ditto this. Purely so the Streamer and the ObjectWriter can talk 524 // to one another. 525 struct DataRegionData { 526 // This enum should be kept in sync w/ the mach-o definition in 527 // llvm/Object/MachOFormat.h. 528 enum KindTy { Data = 1, JumpTable8, JumpTable16, JumpTable32 } Kind; 529 MCSymbol *Start; 530 MCSymbol *End; 531 }; 532 533 class MCAssembler { 534 friend class MCAsmLayout; 535 536 public: 537 typedef std::vector<MCSection *> SectionListType; 538 typedef std::vector<const MCSymbol *> SymbolDataListType; 539 540 typedef pointee_iterator<SectionListType::const_iterator> const_iterator; 541 typedef pointee_iterator<SectionListType::iterator> iterator; 542 543 typedef pointee_iterator<SymbolDataListType::const_iterator> 544 const_symbol_iterator; 545 typedef pointee_iterator<SymbolDataListType::iterator> symbol_iterator; 546 547 typedef iterator_range<symbol_iterator> symbol_range; 548 typedef iterator_range<const_symbol_iterator> const_symbol_range; 549 550 typedef std::vector<IndirectSymbolData>::const_iterator 551 const_indirect_symbol_iterator; 552 typedef std::vector<IndirectSymbolData>::iterator indirect_symbol_iterator; 553 554 typedef std::vector<DataRegionData>::const_iterator 555 const_data_region_iterator; 556 typedef std::vector<DataRegionData>::iterator data_region_iterator; 557 558 /// MachO specific deployment target version info. 559 // A Major version of 0 indicates that no version information was supplied 560 // and so the corresponding load command should not be emitted. 561 typedef struct { 562 MCVersionMinType Kind; 563 unsigned Major; 564 unsigned Minor; 565 unsigned Update; 566 } VersionMinInfoType; 567 568 private: 569 MCAssembler(const MCAssembler &) = delete; 570 void operator=(const MCAssembler &) = delete; 571 572 MCContext &Context; 573 574 MCAsmBackend &Backend; 575 576 MCCodeEmitter &Emitter; 577 578 MCObjectWriter &Writer; 579 580 SectionListType Sections; 581 582 SymbolDataListType Symbols; 583 584 std::vector<IndirectSymbolData> IndirectSymbols; 585 586 std::vector<DataRegionData> DataRegions; 587 588 /// The list of linker options to propagate into the object file. 589 std::vector<std::vector<std::string>> LinkerOptions; 590 591 /// List of declared file names 592 std::vector<std::string> FileNames; 593 594 MCDwarfLineTableParams LTParams; 595 596 /// The set of function symbols for which a .thumb_func directive has 597 /// been seen. 598 // 599 // FIXME: We really would like this in target specific code rather than 600 // here. Maybe when the relocation stuff moves to target specific, 601 // this can go with it? The streamer would need some target specific 602 // refactoring too. 603 mutable SmallPtrSet<const MCSymbol *, 64> ThumbFuncs; 604 605 /// \brief The bundle alignment size currently set in the assembler. 606 /// 607 /// By default it's 0, which means bundling is disabled. 608 unsigned BundleAlignSize; 609 610 unsigned RelaxAll : 1; 611 unsigned SubsectionsViaSymbols : 1; 612 unsigned IncrementalLinkerCompatible : 1; 613 614 /// ELF specific e_header flags 615 // It would be good if there were an MCELFAssembler class to hold this. 616 // ELF header flags are used both by the integrated and standalone assemblers. 617 // Access to the flags is necessary in cases where assembler directives affect 618 // which flags to be set. 619 unsigned ELFHeaderEFlags; 620 621 /// Used to communicate Linker Optimization Hint information between 622 /// the Streamer and the .o writer 623 MCLOHContainer LOHContainer; 624 625 VersionMinInfoType VersionMinInfo; 626 627 private: 628 /// Evaluate a fixup to a relocatable expression and the value which should be 629 /// placed into the fixup. 630 /// 631 /// \param Layout The layout to use for evaluation. 632 /// \param Fixup The fixup to evaluate. 633 /// \param DF The fragment the fixup is inside. 634 /// \param Target [out] On return, the relocatable expression the fixup 635 /// evaluates to. 636 /// \param Value [out] On return, the value of the fixup as currently laid 637 /// out. 638 /// \return Whether the fixup value was fully resolved. This is true if the 639 /// \p Value result is fixed, otherwise the value may change due to 640 /// relocation. 641 bool evaluateFixup(const MCAsmLayout &Layout, const MCFixup &Fixup, 642 const MCFragment *DF, MCValue &Target, 643 uint64_t &Value) const; 644 645 /// Check whether a fixup can be satisfied, or whether it needs to be relaxed 646 /// (increased in size, in order to hold its value correctly). 647 bool fixupNeedsRelaxation(const MCFixup &Fixup, const MCRelaxableFragment *DF, 648 const MCAsmLayout &Layout) const; 649 650 /// Check whether the given fragment needs relaxation. 651 bool fragmentNeedsRelaxation(const MCRelaxableFragment *IF, 652 const MCAsmLayout &Layout) const; 653 654 /// \brief Perform one layout iteration and return true if any offsets 655 /// were adjusted. 656 bool layoutOnce(MCAsmLayout &Layout); 657 658 /// \brief Perform one layout iteration of the given section and return true 659 /// if any offsets were adjusted. 660 bool layoutSectionOnce(MCAsmLayout &Layout, MCSection &Sec); 661 662 bool relaxInstruction(MCAsmLayout &Layout, MCRelaxableFragment &IF); 663 664 bool relaxLEB(MCAsmLayout &Layout, MCLEBFragment &IF); 665 666 bool relaxDwarfLineAddr(MCAsmLayout &Layout, MCDwarfLineAddrFragment &DF); 667 bool relaxDwarfCallFrameFragment(MCAsmLayout &Layout, 668 MCDwarfCallFrameFragment &DF); 669 670 /// finishLayout - Finalize a layout, including fragment lowering. 671 void finishLayout(MCAsmLayout &Layout); 672 673 std::pair<uint64_t, bool> handleFixup(const MCAsmLayout &Layout, 674 MCFragment &F, const MCFixup &Fixup); 675 676 public: 677 /// Compute the effective fragment size assuming it is laid out at the given 678 /// \p SectionAddress and \p FragmentOffset. 679 uint64_t computeFragmentSize(const MCAsmLayout &Layout, 680 const MCFragment &F) const; 681 682 /// Find the symbol which defines the atom containing the given symbol, or 683 /// null if there is no such symbol. 684 const MCSymbol *getAtom(const MCSymbol &S) const; 685 686 /// Check whether a particular symbol is visible to the linker and is required 687 /// in the symbol table, or whether it can be discarded by the assembler. This 688 /// also effects whether the assembler treats the label as potentially 689 /// defining a separate atom. 690 bool isSymbolLinkerVisible(const MCSymbol &SD) const; 691 692 /// Emit the section contents using the given object writer. 693 void writeSectionData(const MCSection *Section, 694 const MCAsmLayout &Layout) const; 695 696 /// Check whether a given symbol has been flagged with .thumb_func. 697 bool isThumbFunc(const MCSymbol *Func) const; 698 699 /// Flag a function symbol as the target of a .thumb_func directive. 700 void setIsThumbFunc(const MCSymbol *Func) { ThumbFuncs.insert(Func); } 701 702 /// ELF e_header flags 703 unsigned getELFHeaderEFlags() const { return ELFHeaderEFlags; } 704 void setELFHeaderEFlags(unsigned Flags) { ELFHeaderEFlags = Flags; } 705 706 /// MachO deployment target version information. 707 const VersionMinInfoType &getVersionMinInfo() const { return VersionMinInfo; } 708 void setVersionMinInfo(MCVersionMinType Kind, unsigned Major, unsigned Minor, 709 unsigned Update) { 710 VersionMinInfo.Kind = Kind; 711 VersionMinInfo.Major = Major; 712 VersionMinInfo.Minor = Minor; 713 VersionMinInfo.Update = Update; 714 } 715 716 public: 717 /// Construct a new assembler instance. 718 // 719 // FIXME: How are we going to parameterize this? Two obvious options are stay 720 // concrete and require clients to pass in a target like object. The other 721 // option is to make this abstract, and have targets provide concrete 722 // implementations as we do with AsmParser. 723 MCAssembler(MCContext &Context_, MCAsmBackend &Backend_, 724 MCCodeEmitter &Emitter_, MCObjectWriter &Writer_); 725 ~MCAssembler(); 726 727 /// Reuse an assembler instance 728 /// 729 void reset(); 730 731 MCContext &getContext() const { return Context; } 732 733 MCAsmBackend &getBackend() const { return Backend; } 734 735 MCCodeEmitter &getEmitter() const { return Emitter; } 736 737 MCObjectWriter &getWriter() const { return Writer; } 738 739 MCDwarfLineTableParams getDWARFLinetableParams() const { return LTParams; } 740 void setDWARFLinetableParams(MCDwarfLineTableParams P) { LTParams = P; } 741 742 /// Finish - Do final processing and write the object to the output stream. 743 /// \p Writer is used for custom object writer (as the MCJIT does), 744 /// if not specified it is automatically created from backend. 745 void Finish(); 746 747 // Layout all section and prepare them for emission. 748 void layout(MCAsmLayout &Layout); 749 750 // FIXME: This does not belong here. 751 bool getSubsectionsViaSymbols() const { return SubsectionsViaSymbols; } 752 void setSubsectionsViaSymbols(bool Value) { SubsectionsViaSymbols = Value; } 753 754 bool isIncrementalLinkerCompatible() const { 755 return IncrementalLinkerCompatible; 756 } 757 void setIncrementalLinkerCompatible(bool Value) { 758 IncrementalLinkerCompatible = Value; 759 } 760 761 bool getRelaxAll() const { return RelaxAll; } 762 void setRelaxAll(bool Value) { RelaxAll = Value; } 763 764 bool isBundlingEnabled() const { return BundleAlignSize != 0; } 765 766 unsigned getBundleAlignSize() const { return BundleAlignSize; } 767 768 void setBundleAlignSize(unsigned Size) { 769 assert((Size == 0 || !(Size & (Size - 1))) && 770 "Expect a power-of-two bundle align size"); 771 BundleAlignSize = Size; 772 } 773 774 /// \name Section List Access 775 /// @{ 776 777 iterator begin() { return Sections.begin(); } 778 const_iterator begin() const { return Sections.begin(); } 779 780 iterator end() { return Sections.end(); } 781 const_iterator end() const { return Sections.end(); } 782 783 size_t size() const { return Sections.size(); } 784 785 /// @} 786 /// \name Symbol List Access 787 /// @{ 788 symbol_iterator symbol_begin() { return Symbols.begin(); } 789 const_symbol_iterator symbol_begin() const { return Symbols.begin(); } 790 791 symbol_iterator symbol_end() { return Symbols.end(); } 792 const_symbol_iterator symbol_end() const { return Symbols.end(); } 793 794 symbol_range symbols() { return make_range(symbol_begin(), symbol_end()); } 795 const_symbol_range symbols() const { 796 return make_range(symbol_begin(), symbol_end()); 797 } 798 799 size_t symbol_size() const { return Symbols.size(); } 800 801 /// @} 802 /// \name Indirect Symbol List Access 803 /// @{ 804 805 // FIXME: This is a total hack, this should not be here. Once things are 806 // factored so that the streamer has direct access to the .o writer, it can 807 // disappear. 808 std::vector<IndirectSymbolData> &getIndirectSymbols() { 809 return IndirectSymbols; 810 } 811 812 indirect_symbol_iterator indirect_symbol_begin() { 813 return IndirectSymbols.begin(); 814 } 815 const_indirect_symbol_iterator indirect_symbol_begin() const { 816 return IndirectSymbols.begin(); 817 } 818 819 indirect_symbol_iterator indirect_symbol_end() { 820 return IndirectSymbols.end(); 821 } 822 const_indirect_symbol_iterator indirect_symbol_end() const { 823 return IndirectSymbols.end(); 824 } 825 826 size_t indirect_symbol_size() const { return IndirectSymbols.size(); } 827 828 /// @} 829 /// \name Linker Option List Access 830 /// @{ 831 832 std::vector<std::vector<std::string>> &getLinkerOptions() { 833 return LinkerOptions; 834 } 835 836 /// @} 837 /// \name Data Region List Access 838 /// @{ 839 840 // FIXME: This is a total hack, this should not be here. Once things are 841 // factored so that the streamer has direct access to the .o writer, it can 842 // disappear. 843 std::vector<DataRegionData> &getDataRegions() { return DataRegions; } 844 845 data_region_iterator data_region_begin() { return DataRegions.begin(); } 846 const_data_region_iterator data_region_begin() const { 847 return DataRegions.begin(); 848 } 849 850 data_region_iterator data_region_end() { return DataRegions.end(); } 851 const_data_region_iterator data_region_end() const { 852 return DataRegions.end(); 853 } 854 855 size_t data_region_size() const { return DataRegions.size(); } 856 857 /// @} 858 /// \name Data Region List Access 859 /// @{ 860 861 // FIXME: This is a total hack, this should not be here. Once things are 862 // factored so that the streamer has direct access to the .o writer, it can 863 // disappear. 864 MCLOHContainer &getLOHContainer() { return LOHContainer; } 865 const MCLOHContainer &getLOHContainer() const { 866 return const_cast<MCAssembler *>(this)->getLOHContainer(); 867 } 868 /// @} 869 /// \name Backend Data Access 870 /// @{ 871 872 bool registerSection(MCSection &Section); 873 874 void registerSymbol(const MCSymbol &Symbol, bool *Created = nullptr); 875 876 ArrayRef<std::string> getFileNames() { return FileNames; } 877 878 void addFileName(StringRef FileName) { 879 if (std::find(FileNames.begin(), FileNames.end(), FileName) == 880 FileNames.end()) 881 FileNames.push_back(FileName); 882 } 883 884 /// \brief Write the necessary bundle padding to the given object writer. 885 /// Expects a fragment \p F containing instructions and its size \p FSize. 886 void writeFragmentPadding(const MCFragment &F, uint64_t FSize, 887 MCObjectWriter *OW) const; 888 889 /// @} 890 891 void dump(); 892 }; 893 894 /// \brief Compute the amount of padding required before the fragment \p F to 895 /// obey bundling restrictions, where \p FOffset is the fragment's offset in 896 /// its section and \p FSize is the fragment's size. 897 uint64_t computeBundlePadding(const MCAssembler &Assembler, const MCFragment *F, 898 uint64_t FOffset, uint64_t FSize); 899 900 } // end namespace llvm 901 902 #endif 903