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