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/SmallPtrSet.h" 15 #include "llvm/ADT/SmallString.h" 16 #include "llvm/ADT/ilist.h" 17 #include "llvm/ADT/ilist_node.h" 18 #include "llvm/MC/MCDirectives.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 #include "llvm/Support/Casting.h" 24 #include "llvm/Support/DataTypes.h" 25 #include <algorithm> 26 #include <vector> // FIXME: Shouldn't be needed. 27 28 namespace llvm { 29 class raw_ostream; 30 class MCAsmLayout; 31 class MCAssembler; 32 class MCContext; 33 class MCCodeEmitter; 34 class MCExpr; 35 class MCFragment; 36 class MCObjectWriter; 37 class MCSection; 38 class MCSectionData; 39 class MCSubtargetInfo; 40 class MCSymbol; 41 class MCSymbolData; 42 class MCValue; 43 class MCAsmBackend; 44 45 class MCFragment : public ilist_node<MCFragment> { 46 friend class MCAsmLayout; 47 48 MCFragment(const MCFragment&) LLVM_DELETED_FUNCTION; 49 void operator=(const MCFragment&) LLVM_DELETED_FUNCTION; 50 51 public: 52 enum FragmentType { 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 }; 63 64 private: 65 FragmentType Kind; 66 67 /// Parent - The data for the section this fragment is in. 68 MCSectionData *Parent; 69 70 /// Atom - The atom this fragment is in, as represented by it's defining 71 /// symbol. 72 MCSymbolData *Atom; 73 74 /// @name Assembler Backend Data 75 /// @{ 76 // 77 // FIXME: This could all be kept private to the assembler implementation. 78 79 /// Offset - The offset of this fragment in its section. This is ~0 until 80 /// initialized. 81 uint64_t Offset; 82 83 /// LayoutOrder - The layout order of this fragment. 84 unsigned LayoutOrder; 85 86 /// @} 87 88 protected: 89 MCFragment(FragmentType _Kind, MCSectionData *_Parent = nullptr); 90 91 public: 92 // Only for sentinel. 93 MCFragment(); 94 virtual ~MCFragment(); 95 getKind()96 FragmentType getKind() const { return Kind; } 97 getParent()98 MCSectionData *getParent() const { return Parent; } setParent(MCSectionData * Value)99 void setParent(MCSectionData *Value) { Parent = Value; } 100 getAtom()101 MCSymbolData *getAtom() const { return Atom; } setAtom(MCSymbolData * Value)102 void setAtom(MCSymbolData *Value) { Atom = Value; } 103 getLayoutOrder()104 unsigned getLayoutOrder() const { return LayoutOrder; } setLayoutOrder(unsigned Value)105 void setLayoutOrder(unsigned Value) { LayoutOrder = Value; } 106 107 /// \brief Does this fragment have instructions emitted into it? By default 108 /// this is false, but specific fragment types may set it to true. hasInstructions()109 virtual bool hasInstructions() const { return false; } 110 111 /// \brief Should this fragment be placed at the end of an aligned bundle? alignToBundleEnd()112 virtual bool alignToBundleEnd() const { return false; } setAlignToBundleEnd(bool V)113 virtual void setAlignToBundleEnd(bool V) { } 114 115 /// \brief Get the padding size that must be inserted before this fragment. 116 /// Used for bundling. By default, no padding is inserted. 117 /// Note that padding size is restricted to 8 bits. This is an optimization 118 /// to reduce the amount of space used for each fragment. In practice, larger 119 /// padding should never be required. getBundlePadding()120 virtual uint8_t getBundlePadding() const { 121 return 0; 122 } 123 124 /// \brief Set the padding size for this fragment. By default it's a no-op, 125 /// and only some fragments have a meaningful implementation. setBundlePadding(uint8_t N)126 virtual void setBundlePadding(uint8_t N) { 127 } 128 129 void dump(); 130 }; 131 132 /// Interface implemented by fragments that contain encoded instructions and/or 133 /// data. 134 /// 135 class MCEncodedFragment : public MCFragment { 136 virtual void anchor(); 137 138 uint8_t BundlePadding; 139 public: 140 MCEncodedFragment(MCFragment::FragmentType FType, MCSectionData *SD = nullptr) MCFragment(FType,SD)141 : MCFragment(FType, SD), BundlePadding(0) 142 { 143 } 144 virtual ~MCEncodedFragment(); 145 146 virtual SmallVectorImpl<char> &getContents() = 0; 147 virtual const SmallVectorImpl<char> &getContents() const = 0; 148 getBundlePadding()149 uint8_t getBundlePadding() const override { 150 return BundlePadding; 151 } 152 setBundlePadding(uint8_t N)153 void setBundlePadding(uint8_t N) override { 154 BundlePadding = N; 155 } 156 classof(const MCFragment * F)157 static bool classof(const MCFragment *F) { 158 MCFragment::FragmentType Kind = F->getKind(); 159 switch (Kind) { 160 default: 161 return false; 162 case MCFragment::FT_Relaxable: 163 case MCFragment::FT_CompactEncodedInst: 164 case MCFragment::FT_Data: 165 return true; 166 } 167 } 168 }; 169 170 /// Interface implemented by fragments that contain encoded instructions and/or 171 /// data and also have fixups registered. 172 /// 173 class MCEncodedFragmentWithFixups : public MCEncodedFragment { 174 void anchor() override; 175 176 public: 177 MCEncodedFragmentWithFixups(MCFragment::FragmentType FType, 178 MCSectionData *SD = nullptr) MCEncodedFragment(FType,SD)179 : MCEncodedFragment(FType, SD) 180 { 181 } 182 183 virtual ~MCEncodedFragmentWithFixups(); 184 185 typedef SmallVectorImpl<MCFixup>::const_iterator const_fixup_iterator; 186 typedef SmallVectorImpl<MCFixup>::iterator fixup_iterator; 187 188 virtual SmallVectorImpl<MCFixup> &getFixups() = 0; 189 virtual const SmallVectorImpl<MCFixup> &getFixups() const = 0; 190 191 virtual fixup_iterator fixup_begin() = 0; 192 virtual const_fixup_iterator fixup_begin() const = 0; 193 virtual fixup_iterator fixup_end() = 0; 194 virtual const_fixup_iterator fixup_end() const = 0; 195 classof(const MCFragment * F)196 static bool classof(const MCFragment *F) { 197 MCFragment::FragmentType Kind = F->getKind(); 198 return Kind == MCFragment::FT_Relaxable || Kind == MCFragment::FT_Data; 199 } 200 }; 201 202 /// Fragment for data and encoded instructions. 203 /// 204 class MCDataFragment : public MCEncodedFragmentWithFixups { 205 void anchor() override; 206 207 /// \brief Does this fragment contain encoded instructions anywhere in it? 208 bool HasInstructions; 209 210 /// \brief Should this fragment be aligned to the end of a bundle? 211 bool AlignToBundleEnd; 212 213 SmallVector<char, 32> Contents; 214 215 /// Fixups - The list of fixups in this fragment. 216 SmallVector<MCFixup, 4> Fixups; 217 public: 218 MCDataFragment(MCSectionData *SD = nullptr) MCEncodedFragmentWithFixups(FT_Data,SD)219 : MCEncodedFragmentWithFixups(FT_Data, SD), 220 HasInstructions(false), AlignToBundleEnd(false) 221 { 222 } 223 getContents()224 SmallVectorImpl<char> &getContents() override { return Contents; } getContents()225 const SmallVectorImpl<char> &getContents() const override { 226 return Contents; 227 } 228 getFixups()229 SmallVectorImpl<MCFixup> &getFixups() override { 230 return Fixups; 231 } 232 getFixups()233 const SmallVectorImpl<MCFixup> &getFixups() const override { 234 return Fixups; 235 } 236 hasInstructions()237 bool hasInstructions() const override { return HasInstructions; } setHasInstructions(bool V)238 virtual void setHasInstructions(bool V) { HasInstructions = V; } 239 alignToBundleEnd()240 bool alignToBundleEnd() const override { return AlignToBundleEnd; } setAlignToBundleEnd(bool V)241 void setAlignToBundleEnd(bool V) override { AlignToBundleEnd = V; } 242 fixup_begin()243 fixup_iterator fixup_begin() override { return Fixups.begin(); } fixup_begin()244 const_fixup_iterator fixup_begin() const override { return Fixups.begin(); } 245 fixup_end()246 fixup_iterator fixup_end() override {return Fixups.end();} fixup_end()247 const_fixup_iterator fixup_end() const override {return Fixups.end();} 248 classof(const MCFragment * F)249 static bool classof(const MCFragment *F) { 250 return F->getKind() == MCFragment::FT_Data; 251 } 252 }; 253 254 /// This is a compact (memory-size-wise) fragment for holding an encoded 255 /// instruction (non-relaxable) that has no fixups registered. When applicable, 256 /// it can be used instead of MCDataFragment and lead to lower memory 257 /// consumption. 258 /// 259 class MCCompactEncodedInstFragment : public MCEncodedFragment { 260 void anchor() override; 261 262 /// \brief Should this fragment be aligned to the end of a bundle? 263 bool AlignToBundleEnd; 264 265 SmallVector<char, 4> Contents; 266 public: 267 MCCompactEncodedInstFragment(MCSectionData *SD = nullptr) MCEncodedFragment(FT_CompactEncodedInst,SD)268 : MCEncodedFragment(FT_CompactEncodedInst, SD), AlignToBundleEnd(false) 269 { 270 } 271 hasInstructions()272 bool hasInstructions() const override { 273 return true; 274 } 275 getContents()276 SmallVectorImpl<char> &getContents() override { return Contents; } getContents()277 const SmallVectorImpl<char> &getContents() const override { return Contents; } 278 alignToBundleEnd()279 bool alignToBundleEnd() const override { return AlignToBundleEnd; } setAlignToBundleEnd(bool V)280 void setAlignToBundleEnd(bool V) override { AlignToBundleEnd = V; } 281 classof(const MCFragment * F)282 static bool classof(const MCFragment *F) { 283 return F->getKind() == MCFragment::FT_CompactEncodedInst; 284 } 285 }; 286 287 /// A relaxable fragment holds on to its MCInst, since it may need to be 288 /// relaxed during the assembler layout and relaxation stage. 289 /// 290 class MCRelaxableFragment : public MCEncodedFragmentWithFixups { 291 void anchor() override; 292 293 /// Inst - The instruction this is a fragment for. 294 MCInst Inst; 295 296 /// STI - The MCSubtargetInfo in effect when the instruction was encoded. 297 /// Keep a copy instead of a reference to make sure that updates to STI 298 /// in the assembler are not seen here. 299 const MCSubtargetInfo STI; 300 301 /// Contents - Binary data for the currently encoded instruction. 302 SmallVector<char, 8> Contents; 303 304 /// Fixups - The list of fixups in this fragment. 305 SmallVector<MCFixup, 1> Fixups; 306 307 public: 308 MCRelaxableFragment(const MCInst &_Inst, 309 const MCSubtargetInfo &_STI, 310 MCSectionData *SD = nullptr) MCEncodedFragmentWithFixups(FT_Relaxable,SD)311 : MCEncodedFragmentWithFixups(FT_Relaxable, SD), Inst(_Inst), STI(_STI) { 312 } 313 getContents()314 SmallVectorImpl<char> &getContents() override { return Contents; } getContents()315 const SmallVectorImpl<char> &getContents() const override { return Contents; } 316 getInst()317 const MCInst &getInst() const { return Inst; } setInst(const MCInst & Value)318 void setInst(const MCInst& Value) { Inst = Value; } 319 getSubtargetInfo()320 const MCSubtargetInfo &getSubtargetInfo() { return STI; } 321 getFixups()322 SmallVectorImpl<MCFixup> &getFixups() override { 323 return Fixups; 324 } 325 getFixups()326 const SmallVectorImpl<MCFixup> &getFixups() const override { 327 return Fixups; 328 } 329 hasInstructions()330 bool hasInstructions() const override { return true; } 331 fixup_begin()332 fixup_iterator fixup_begin() override { return Fixups.begin(); } fixup_begin()333 const_fixup_iterator fixup_begin() const override { return Fixups.begin(); } 334 fixup_end()335 fixup_iterator fixup_end() override {return Fixups.end();} fixup_end()336 const_fixup_iterator fixup_end() const override {return Fixups.end();} 337 classof(const MCFragment * F)338 static bool classof(const MCFragment *F) { 339 return F->getKind() == MCFragment::FT_Relaxable; 340 } 341 }; 342 343 class MCAlignFragment : public MCFragment { 344 virtual void anchor(); 345 346 /// Alignment - The alignment to ensure, in bytes. 347 unsigned Alignment; 348 349 /// Value - Value to use for filling padding bytes. 350 int64_t Value; 351 352 /// ValueSize - The size of the integer (in bytes) of \p Value. 353 unsigned ValueSize; 354 355 /// MaxBytesToEmit - The maximum number of bytes to emit; if the alignment 356 /// cannot be satisfied in this width then this fragment is ignored. 357 unsigned MaxBytesToEmit; 358 359 /// EmitNops - Flag to indicate that (optimal) NOPs should be emitted instead 360 /// of using the provided value. The exact interpretation of this flag is 361 /// target dependent. 362 bool EmitNops : 1; 363 364 public: 365 MCAlignFragment(unsigned _Alignment, int64_t _Value, unsigned _ValueSize, 366 unsigned _MaxBytesToEmit, MCSectionData *SD = nullptr) MCFragment(FT_Align,SD)367 : MCFragment(FT_Align, SD), Alignment(_Alignment), 368 Value(_Value),ValueSize(_ValueSize), 369 MaxBytesToEmit(_MaxBytesToEmit), EmitNops(false) {} 370 371 /// @name Accessors 372 /// @{ 373 getAlignment()374 unsigned getAlignment() const { return Alignment; } 375 getValue()376 int64_t getValue() const { return Value; } 377 getValueSize()378 unsigned getValueSize() const { return ValueSize; } 379 getMaxBytesToEmit()380 unsigned getMaxBytesToEmit() const { return MaxBytesToEmit; } 381 hasEmitNops()382 bool hasEmitNops() const { return EmitNops; } setEmitNops(bool Value)383 void setEmitNops(bool Value) { EmitNops = Value; } 384 385 /// @} 386 classof(const MCFragment * F)387 static bool classof(const MCFragment *F) { 388 return F->getKind() == MCFragment::FT_Align; 389 } 390 }; 391 392 class MCFillFragment : public MCFragment { 393 virtual void anchor(); 394 395 /// Value - Value to use for filling bytes. 396 int64_t Value; 397 398 /// ValueSize - The size (in bytes) of \p Value to use when filling, or 0 if 399 /// this is a virtual fill fragment. 400 unsigned ValueSize; 401 402 /// Size - The number of bytes to insert. 403 uint64_t Size; 404 405 public: 406 MCFillFragment(int64_t _Value, unsigned _ValueSize, uint64_t _Size, 407 MCSectionData *SD = nullptr) MCFragment(FT_Fill,SD)408 : MCFragment(FT_Fill, SD), 409 Value(_Value), ValueSize(_ValueSize), Size(_Size) { 410 assert((!ValueSize || (Size % ValueSize) == 0) && 411 "Fill size must be a multiple of the value size!"); 412 } 413 414 /// @name Accessors 415 /// @{ 416 getValue()417 int64_t getValue() const { return Value; } 418 getValueSize()419 unsigned getValueSize() const { return ValueSize; } 420 getSize()421 uint64_t getSize() const { return Size; } 422 423 /// @} 424 classof(const MCFragment * F)425 static bool classof(const MCFragment *F) { 426 return F->getKind() == MCFragment::FT_Fill; 427 } 428 }; 429 430 class MCOrgFragment : public MCFragment { 431 virtual void anchor(); 432 433 /// Offset - The offset this fragment should start at. 434 const MCExpr *Offset; 435 436 /// Value - Value to use for filling bytes. 437 int8_t Value; 438 439 public: 440 MCOrgFragment(const MCExpr &_Offset, int8_t _Value, 441 MCSectionData *SD = nullptr) MCFragment(FT_Org,SD)442 : MCFragment(FT_Org, SD), 443 Offset(&_Offset), Value(_Value) {} 444 445 /// @name Accessors 446 /// @{ 447 getOffset()448 const MCExpr &getOffset() const { return *Offset; } 449 getValue()450 uint8_t getValue() const { return Value; } 451 452 /// @} 453 classof(const MCFragment * F)454 static bool classof(const MCFragment *F) { 455 return F->getKind() == MCFragment::FT_Org; 456 } 457 }; 458 459 class MCLEBFragment : public MCFragment { 460 virtual void anchor(); 461 462 /// Value - The value this fragment should contain. 463 const MCExpr *Value; 464 465 /// IsSigned - True if this is a sleb128, false if uleb128. 466 bool IsSigned; 467 468 SmallString<8> Contents; 469 public: 470 MCLEBFragment(const MCExpr &Value_, bool IsSigned_, 471 MCSectionData *SD = nullptr) MCFragment(FT_LEB,SD)472 : MCFragment(FT_LEB, SD), 473 Value(&Value_), IsSigned(IsSigned_) { Contents.push_back(0); } 474 475 /// @name Accessors 476 /// @{ 477 getValue()478 const MCExpr &getValue() const { return *Value; } 479 isSigned()480 bool isSigned() const { return IsSigned; } 481 getContents()482 SmallString<8> &getContents() { return Contents; } getContents()483 const SmallString<8> &getContents() const { return Contents; } 484 485 /// @} 486 classof(const MCFragment * F)487 static bool classof(const MCFragment *F) { 488 return F->getKind() == MCFragment::FT_LEB; 489 } 490 }; 491 492 class MCDwarfLineAddrFragment : public MCFragment { 493 virtual void anchor(); 494 495 /// LineDelta - the value of the difference between the two line numbers 496 /// between two .loc dwarf directives. 497 int64_t LineDelta; 498 499 /// AddrDelta - The expression for the difference of the two symbols that 500 /// make up the address delta between two .loc dwarf directives. 501 const MCExpr *AddrDelta; 502 503 SmallString<8> Contents; 504 505 public: 506 MCDwarfLineAddrFragment(int64_t _LineDelta, const MCExpr &_AddrDelta, 507 MCSectionData *SD = nullptr) MCFragment(FT_Dwarf,SD)508 : MCFragment(FT_Dwarf, SD), 509 LineDelta(_LineDelta), AddrDelta(&_AddrDelta) { Contents.push_back(0); } 510 511 /// @name Accessors 512 /// @{ 513 getLineDelta()514 int64_t getLineDelta() const { return LineDelta; } 515 getAddrDelta()516 const MCExpr &getAddrDelta() const { return *AddrDelta; } 517 getContents()518 SmallString<8> &getContents() { return Contents; } getContents()519 const SmallString<8> &getContents() const { return Contents; } 520 521 /// @} 522 classof(const MCFragment * F)523 static bool classof(const MCFragment *F) { 524 return F->getKind() == MCFragment::FT_Dwarf; 525 } 526 }; 527 528 class MCDwarfCallFrameFragment : public MCFragment { 529 virtual void anchor(); 530 531 /// AddrDelta - The expression for the difference of the two symbols that 532 /// make up the address delta between two .cfi_* dwarf directives. 533 const MCExpr *AddrDelta; 534 535 SmallString<8> Contents; 536 537 public: 538 MCDwarfCallFrameFragment(const MCExpr &_AddrDelta, 539 MCSectionData *SD = nullptr) MCFragment(FT_DwarfFrame,SD)540 : MCFragment(FT_DwarfFrame, SD), 541 AddrDelta(&_AddrDelta) { Contents.push_back(0); } 542 543 /// @name Accessors 544 /// @{ 545 getAddrDelta()546 const MCExpr &getAddrDelta() const { return *AddrDelta; } 547 getContents()548 SmallString<8> &getContents() { return Contents; } getContents()549 const SmallString<8> &getContents() const { return Contents; } 550 551 /// @} 552 classof(const MCFragment * F)553 static bool classof(const MCFragment *F) { 554 return F->getKind() == MCFragment::FT_DwarfFrame; 555 } 556 }; 557 558 // FIXME: Should this be a separate class, or just merged into MCSection? Since 559 // we anticipate the fast path being through an MCAssembler, the only reason to 560 // keep it out is for API abstraction. 561 class MCSectionData : public ilist_node<MCSectionData> { 562 friend class MCAsmLayout; 563 564 MCSectionData(const MCSectionData&) LLVM_DELETED_FUNCTION; 565 void operator=(const MCSectionData&) LLVM_DELETED_FUNCTION; 566 567 public: 568 typedef iplist<MCFragment> FragmentListType; 569 570 typedef FragmentListType::const_iterator const_iterator; 571 typedef FragmentListType::iterator iterator; 572 573 typedef FragmentListType::const_reverse_iterator const_reverse_iterator; 574 typedef FragmentListType::reverse_iterator reverse_iterator; 575 576 /// \brief Express the state of bundle locked groups while emitting code. 577 enum BundleLockStateType { 578 NotBundleLocked, 579 BundleLocked, 580 BundleLockedAlignToEnd 581 }; 582 private: 583 FragmentListType Fragments; 584 const MCSection *Section; 585 586 /// Ordinal - The section index in the assemblers section list. 587 unsigned Ordinal; 588 589 /// LayoutOrder - The index of this section in the layout order. 590 unsigned LayoutOrder; 591 592 /// Alignment - The maximum alignment seen in this section. 593 unsigned Alignment; 594 595 /// \brief Keeping track of bundle-locked state. 596 BundleLockStateType BundleLockState; 597 598 /// \brief We've seen a bundle_lock directive but not its first instruction 599 /// yet. 600 bool BundleGroupBeforeFirstInst; 601 602 /// @name Assembler Backend Data 603 /// @{ 604 // 605 // FIXME: This could all be kept private to the assembler implementation. 606 607 /// HasInstructions - Whether this section has had instructions emitted into 608 /// it. 609 unsigned HasInstructions : 1; 610 611 /// Mapping from subsection number to insertion point for subsection numbers 612 /// below that number. 613 SmallVector<std::pair<unsigned, MCFragment *>, 1> SubsectionFragmentMap; 614 615 /// @} 616 617 public: 618 // Only for use as sentinel. 619 MCSectionData(); 620 MCSectionData(const MCSection &Section, MCAssembler *A = nullptr); 621 getSection()622 const MCSection &getSection() const { return *Section; } 623 getAlignment()624 unsigned getAlignment() const { return Alignment; } setAlignment(unsigned Value)625 void setAlignment(unsigned Value) { Alignment = Value; } 626 hasInstructions()627 bool hasInstructions() const { return HasInstructions; } setHasInstructions(bool Value)628 void setHasInstructions(bool Value) { HasInstructions = Value; } 629 getOrdinal()630 unsigned getOrdinal() const { return Ordinal; } setOrdinal(unsigned Value)631 void setOrdinal(unsigned Value) { Ordinal = Value; } 632 getLayoutOrder()633 unsigned getLayoutOrder() const { return LayoutOrder; } setLayoutOrder(unsigned Value)634 void setLayoutOrder(unsigned Value) { LayoutOrder = Value; } 635 636 /// @name Fragment Access 637 /// @{ 638 getFragmentList()639 const FragmentListType &getFragmentList() const { return Fragments; } getFragmentList()640 FragmentListType &getFragmentList() { return Fragments; } 641 begin()642 iterator begin() { return Fragments.begin(); } begin()643 const_iterator begin() const { return Fragments.begin(); } 644 end()645 iterator end() { return Fragments.end(); } end()646 const_iterator end() const { return Fragments.end(); } 647 rbegin()648 reverse_iterator rbegin() { return Fragments.rbegin(); } rbegin()649 const_reverse_iterator rbegin() const { return Fragments.rbegin(); } 650 rend()651 reverse_iterator rend() { return Fragments.rend(); } rend()652 const_reverse_iterator rend() const { return Fragments.rend(); } 653 size()654 size_t size() const { return Fragments.size(); } 655 empty()656 bool empty() const { return Fragments.empty(); } 657 658 iterator getSubsectionInsertionPoint(unsigned Subsection); 659 isBundleLocked()660 bool isBundleLocked() const { 661 return BundleLockState != NotBundleLocked; 662 } 663 getBundleLockState()664 BundleLockStateType getBundleLockState() const { 665 return BundleLockState; 666 } 667 setBundleLockState(BundleLockStateType NewState)668 void setBundleLockState(BundleLockStateType NewState) { 669 BundleLockState = NewState; 670 } 671 isBundleGroupBeforeFirstInst()672 bool isBundleGroupBeforeFirstInst() const { 673 return BundleGroupBeforeFirstInst; 674 } 675 setBundleGroupBeforeFirstInst(bool IsFirst)676 void setBundleGroupBeforeFirstInst(bool IsFirst) { 677 BundleGroupBeforeFirstInst = IsFirst; 678 } 679 680 void dump(); 681 682 /// @} 683 }; 684 685 // FIXME: Same concerns as with SectionData. 686 class MCSymbolData : public ilist_node<MCSymbolData> { 687 public: 688 const MCSymbol *Symbol; 689 690 /// Fragment - The fragment this symbol's value is relative to, if any. 691 MCFragment *Fragment; 692 693 /// Offset - The offset to apply to the fragment address to form this symbol's 694 /// value. 695 uint64_t Offset; 696 697 /// IsExternal - True if this symbol is visible outside this translation 698 /// unit. 699 unsigned IsExternal : 1; 700 701 /// IsPrivateExtern - True if this symbol is private extern. 702 unsigned IsPrivateExtern : 1; 703 704 /// CommonSize - The size of the symbol, if it is 'common', or 0. 705 // 706 // FIXME: Pack this in with other fields? We could put it in offset, since a 707 // common symbol can never get a definition. 708 uint64_t CommonSize; 709 710 /// SymbolSize - An expression describing how to calculate the size of 711 /// a symbol. If a symbol has no size this field will be NULL. 712 const MCExpr *SymbolSize; 713 714 /// CommonAlign - The alignment of the symbol, if it is 'common'. 715 // 716 // FIXME: Pack this in with other fields? 717 unsigned CommonAlign; 718 719 /// Flags - The Flags field is used by object file implementations to store 720 /// additional per symbol information which is not easily classified. 721 uint32_t Flags; 722 723 /// Index - Index field, for use by the object file implementation. 724 uint64_t Index; 725 726 public: 727 // Only for use as sentinel. 728 MCSymbolData(); 729 MCSymbolData(const MCSymbol &_Symbol, MCFragment *_Fragment, uint64_t _Offset, 730 MCAssembler *A = nullptr); 731 732 /// @name Accessors 733 /// @{ 734 getSymbol()735 const MCSymbol &getSymbol() const { return *Symbol; } 736 getFragment()737 MCFragment *getFragment() const { return Fragment; } setFragment(MCFragment * Value)738 void setFragment(MCFragment *Value) { Fragment = Value; } 739 getOffset()740 uint64_t getOffset() const { return Offset; } setOffset(uint64_t Value)741 void setOffset(uint64_t Value) { Offset = Value; } 742 743 /// @} 744 /// @name Symbol Attributes 745 /// @{ 746 isExternal()747 bool isExternal() const { return IsExternal; } setExternal(bool Value)748 void setExternal(bool Value) { IsExternal = Value; } 749 isPrivateExtern()750 bool isPrivateExtern() const { return IsPrivateExtern; } setPrivateExtern(bool Value)751 void setPrivateExtern(bool Value) { IsPrivateExtern = Value; } 752 753 /// isCommon - Is this a 'common' symbol. isCommon()754 bool isCommon() const { return CommonSize != 0; } 755 756 /// setCommon - Mark this symbol as being 'common'. 757 /// 758 /// \param Size - The size of the symbol. 759 /// \param Align - The alignment of the symbol. setCommon(uint64_t Size,unsigned Align)760 void setCommon(uint64_t Size, unsigned Align) { 761 CommonSize = Size; 762 CommonAlign = Align; 763 } 764 765 /// getCommonSize - Return the size of a 'common' symbol. getCommonSize()766 uint64_t getCommonSize() const { 767 assert(isCommon() && "Not a 'common' symbol!"); 768 return CommonSize; 769 } 770 setSize(const MCExpr * SS)771 void setSize(const MCExpr *SS) { 772 SymbolSize = SS; 773 } 774 getSize()775 const MCExpr *getSize() const { 776 return SymbolSize; 777 } 778 779 780 /// getCommonAlignment - Return the alignment of a 'common' symbol. getCommonAlignment()781 unsigned getCommonAlignment() const { 782 assert(isCommon() && "Not a 'common' symbol!"); 783 return CommonAlign; 784 } 785 786 /// getFlags - Get the (implementation defined) symbol flags. getFlags()787 uint32_t getFlags() const { return Flags; } 788 789 /// setFlags - Set the (implementation defined) symbol flags. setFlags(uint32_t Value)790 void setFlags(uint32_t Value) { Flags = Value; } 791 792 /// modifyFlags - Modify the flags via a mask modifyFlags(uint32_t Value,uint32_t Mask)793 void modifyFlags(uint32_t Value, uint32_t Mask) { 794 Flags = (Flags & ~Mask) | Value; 795 } 796 797 /// getIndex - Get the (implementation defined) index. getIndex()798 uint64_t getIndex() const { return Index; } 799 800 /// setIndex - Set the (implementation defined) index. setIndex(uint64_t Value)801 void setIndex(uint64_t Value) { Index = Value; } 802 803 /// @} 804 805 void dump() const; 806 }; 807 808 // FIXME: This really doesn't belong here. See comments below. 809 struct IndirectSymbolData { 810 MCSymbol *Symbol; 811 MCSectionData *SectionData; 812 }; 813 814 // FIXME: Ditto this. Purely so the Streamer and the ObjectWriter can talk 815 // to one another. 816 struct DataRegionData { 817 // This enum should be kept in sync w/ the mach-o definition in 818 // llvm/Object/MachOFormat.h. 819 enum KindTy { Data = 1, JumpTable8, JumpTable16, JumpTable32 } Kind; 820 MCSymbol *Start; 821 MCSymbol *End; 822 }; 823 824 class MCAssembler { 825 friend class MCAsmLayout; 826 827 public: 828 typedef iplist<MCSectionData> SectionDataListType; 829 typedef iplist<MCSymbolData> SymbolDataListType; 830 831 typedef SectionDataListType::const_iterator const_iterator; 832 typedef SectionDataListType::iterator iterator; 833 834 typedef SymbolDataListType::const_iterator const_symbol_iterator; 835 typedef SymbolDataListType::iterator symbol_iterator; 836 837 typedef iterator_range<symbol_iterator> symbol_range; 838 typedef iterator_range<const_symbol_iterator> const_symbol_range; 839 840 typedef std::vector<std::string> FileNameVectorType; 841 typedef FileNameVectorType::const_iterator const_file_name_iterator; 842 843 typedef std::vector<IndirectSymbolData>::const_iterator 844 const_indirect_symbol_iterator; 845 typedef std::vector<IndirectSymbolData>::iterator indirect_symbol_iterator; 846 847 typedef std::vector<DataRegionData>::const_iterator 848 const_data_region_iterator; 849 typedef std::vector<DataRegionData>::iterator data_region_iterator; 850 851 /// MachO specific deployment target version info. 852 // A Major version of 0 indicates that no version information was supplied 853 // and so the corresponding load command should not be emitted. 854 typedef struct { 855 MCVersionMinType Kind; 856 unsigned Major; 857 unsigned Minor; 858 unsigned Update; 859 } VersionMinInfoType; 860 private: 861 MCAssembler(const MCAssembler&) LLVM_DELETED_FUNCTION; 862 void operator=(const MCAssembler&) LLVM_DELETED_FUNCTION; 863 864 MCContext &Context; 865 866 MCAsmBackend &Backend; 867 868 MCCodeEmitter &Emitter; 869 870 MCObjectWriter &Writer; 871 872 raw_ostream &OS; 873 874 iplist<MCSectionData> Sections; 875 876 iplist<MCSymbolData> Symbols; 877 878 /// The map of sections to their associated assembler backend data. 879 // 880 // FIXME: Avoid this indirection? 881 DenseMap<const MCSection*, MCSectionData*> SectionMap; 882 883 /// The map of symbols to their associated assembler backend data. 884 // 885 // FIXME: Avoid this indirection? 886 DenseMap<const MCSymbol*, MCSymbolData*> SymbolMap; 887 888 std::vector<IndirectSymbolData> IndirectSymbols; 889 890 std::vector<DataRegionData> DataRegions; 891 892 /// The list of linker options to propagate into the object file. 893 std::vector<std::vector<std::string> > LinkerOptions; 894 895 /// List of declared file names 896 FileNameVectorType FileNames; 897 898 /// The set of function symbols for which a .thumb_func directive has 899 /// been seen. 900 // 901 // FIXME: We really would like this in target specific code rather than 902 // here. Maybe when the relocation stuff moves to target specific, 903 // this can go with it? The streamer would need some target specific 904 // refactoring too. 905 mutable SmallPtrSet<const MCSymbol*, 64> ThumbFuncs; 906 907 /// \brief The bundle alignment size currently set in the assembler. 908 /// 909 /// By default it's 0, which means bundling is disabled. 910 unsigned BundleAlignSize; 911 912 unsigned RelaxAll : 1; 913 unsigned NoExecStack : 1; 914 unsigned SubsectionsViaSymbols : 1; 915 916 /// ELF specific e_header flags 917 // It would be good if there were an MCELFAssembler class to hold this. 918 // ELF header flags are used both by the integrated and standalone assemblers. 919 // Access to the flags is necessary in cases where assembler directives affect 920 // which flags to be set. 921 unsigned ELFHeaderEFlags; 922 923 /// Used to communicate Linker Optimization Hint information between 924 /// the Streamer and the .o writer 925 MCLOHContainer LOHContainer; 926 927 VersionMinInfoType VersionMinInfo; 928 private: 929 /// Evaluate a fixup to a relocatable expression and the value which should be 930 /// placed into the fixup. 931 /// 932 /// \param Layout The layout to use for evaluation. 933 /// \param Fixup The fixup to evaluate. 934 /// \param DF The fragment the fixup is inside. 935 /// \param Target [out] On return, the relocatable expression the fixup 936 /// evaluates to. 937 /// \param Value [out] On return, the value of the fixup as currently laid 938 /// out. 939 /// \return Whether the fixup value was fully resolved. This is true if the 940 /// \p Value result is fixed, otherwise the value may change due to 941 /// relocation. 942 bool evaluateFixup(const MCAsmLayout &Layout, 943 const MCFixup &Fixup, const MCFragment *DF, 944 MCValue &Target, uint64_t &Value) const; 945 946 /// Check whether a fixup can be satisfied, or whether it needs to be relaxed 947 /// (increased in size, in order to hold its value correctly). 948 bool fixupNeedsRelaxation(const MCFixup &Fixup, const MCRelaxableFragment *DF, 949 const MCAsmLayout &Layout) const; 950 951 /// Check whether the given fragment needs relaxation. 952 bool fragmentNeedsRelaxation(const MCRelaxableFragment *IF, 953 const MCAsmLayout &Layout) const; 954 955 /// \brief Perform one layout iteration and return true if any offsets 956 /// were adjusted. 957 bool layoutOnce(MCAsmLayout &Layout); 958 959 /// \brief Perform one layout iteration of the given section and return true 960 /// if any offsets were adjusted. 961 bool layoutSectionOnce(MCAsmLayout &Layout, MCSectionData &SD); 962 963 bool relaxInstruction(MCAsmLayout &Layout, MCRelaxableFragment &IF); 964 965 bool relaxLEB(MCAsmLayout &Layout, MCLEBFragment &IF); 966 967 bool relaxDwarfLineAddr(MCAsmLayout &Layout, MCDwarfLineAddrFragment &DF); 968 bool relaxDwarfCallFrameFragment(MCAsmLayout &Layout, 969 MCDwarfCallFrameFragment &DF); 970 971 /// finishLayout - Finalize a layout, including fragment lowering. 972 void finishLayout(MCAsmLayout &Layout); 973 974 std::pair<uint64_t, bool> handleFixup(const MCAsmLayout &Layout, 975 MCFragment &F, const MCFixup &Fixup); 976 977 public: 978 /// Compute the effective fragment size assuming it is laid out at the given 979 /// \p SectionAddress and \p FragmentOffset. 980 uint64_t computeFragmentSize(const MCAsmLayout &Layout, 981 const MCFragment &F) const; 982 983 /// Find the symbol which defines the atom containing the given symbol, or 984 /// null if there is no such symbol. 985 const MCSymbolData *getAtom(const MCSymbolData *Symbol) const; 986 987 /// Check whether a particular symbol is visible to the linker and is required 988 /// in the symbol table, or whether it can be discarded by the assembler. This 989 /// also effects whether the assembler treats the label as potentially 990 /// defining a separate atom. 991 bool isSymbolLinkerVisible(const MCSymbol &SD) const; 992 993 /// Emit the section contents using the given object writer. 994 void writeSectionData(const MCSectionData *Section, 995 const MCAsmLayout &Layout) const; 996 997 /// Check whether a given symbol has been flagged with .thumb_func. 998 bool isThumbFunc(const MCSymbol *Func) const; 999 1000 /// Flag a function symbol as the target of a .thumb_func directive. setIsThumbFunc(const MCSymbol * Func)1001 void setIsThumbFunc(const MCSymbol *Func) { ThumbFuncs.insert(Func); } 1002 1003 /// ELF e_header flags getELFHeaderEFlags()1004 unsigned getELFHeaderEFlags() const {return ELFHeaderEFlags;} setELFHeaderEFlags(unsigned Flags)1005 void setELFHeaderEFlags(unsigned Flags) { ELFHeaderEFlags = Flags;} 1006 1007 /// MachO deployment target version information. getVersionMinInfo()1008 const VersionMinInfoType &getVersionMinInfo() const { return VersionMinInfo; } setVersionMinInfo(MCVersionMinType Kind,unsigned Major,unsigned Minor,unsigned Update)1009 void setVersionMinInfo(MCVersionMinType Kind, unsigned Major, unsigned Minor, 1010 unsigned Update) { 1011 VersionMinInfo.Kind = Kind; 1012 VersionMinInfo.Major = Major; 1013 VersionMinInfo.Minor = Minor; 1014 VersionMinInfo.Update = Update; 1015 } 1016 1017 public: 1018 /// Construct a new assembler instance. 1019 /// 1020 /// \param OS The stream to output to. 1021 // 1022 // FIXME: How are we going to parameterize this? Two obvious options are stay 1023 // concrete and require clients to pass in a target like object. The other 1024 // option is to make this abstract, and have targets provide concrete 1025 // implementations as we do with AsmParser. 1026 MCAssembler(MCContext &Context_, MCAsmBackend &Backend_, 1027 MCCodeEmitter &Emitter_, MCObjectWriter &Writer_, 1028 raw_ostream &OS); 1029 ~MCAssembler(); 1030 1031 /// Reuse an assembler instance 1032 /// 1033 void reset(); 1034 getContext()1035 MCContext &getContext() const { return Context; } 1036 getBackend()1037 MCAsmBackend &getBackend() const { return Backend; } 1038 getEmitter()1039 MCCodeEmitter &getEmitter() const { return Emitter; } 1040 getWriter()1041 MCObjectWriter &getWriter() const { return Writer; } 1042 1043 /// Finish - Do final processing and write the object to the output stream. 1044 /// \p Writer is used for custom object writer (as the MCJIT does), 1045 /// if not specified it is automatically created from backend. 1046 void Finish(); 1047 1048 // FIXME: This does not belong here. getSubsectionsViaSymbols()1049 bool getSubsectionsViaSymbols() const { 1050 return SubsectionsViaSymbols; 1051 } setSubsectionsViaSymbols(bool Value)1052 void setSubsectionsViaSymbols(bool Value) { 1053 SubsectionsViaSymbols = Value; 1054 } 1055 getRelaxAll()1056 bool getRelaxAll() const { return RelaxAll; } setRelaxAll(bool Value)1057 void setRelaxAll(bool Value) { RelaxAll = Value; } 1058 getNoExecStack()1059 bool getNoExecStack() const { return NoExecStack; } setNoExecStack(bool Value)1060 void setNoExecStack(bool Value) { NoExecStack = Value; } 1061 isBundlingEnabled()1062 bool isBundlingEnabled() const { 1063 return BundleAlignSize != 0; 1064 } 1065 getBundleAlignSize()1066 unsigned getBundleAlignSize() const { 1067 return BundleAlignSize; 1068 } 1069 setBundleAlignSize(unsigned Size)1070 void setBundleAlignSize(unsigned Size) { 1071 assert((Size == 0 || !(Size & (Size - 1))) && 1072 "Expect a power-of-two bundle align size"); 1073 BundleAlignSize = Size; 1074 } 1075 1076 /// @name Section List Access 1077 /// @{ 1078 getSectionList()1079 const SectionDataListType &getSectionList() const { return Sections; } getSectionList()1080 SectionDataListType &getSectionList() { return Sections; } 1081 begin()1082 iterator begin() { return Sections.begin(); } begin()1083 const_iterator begin() const { return Sections.begin(); } 1084 end()1085 iterator end() { return Sections.end(); } end()1086 const_iterator end() const { return Sections.end(); } 1087 size()1088 size_t size() const { return Sections.size(); } 1089 1090 /// @} 1091 /// @name Symbol List Access 1092 /// @{ 1093 getSymbolList()1094 const SymbolDataListType &getSymbolList() const { return Symbols; } getSymbolList()1095 SymbolDataListType &getSymbolList() { return Symbols; } 1096 symbol_begin()1097 symbol_iterator symbol_begin() { return Symbols.begin(); } symbol_begin()1098 const_symbol_iterator symbol_begin() const { return Symbols.begin(); } 1099 symbol_end()1100 symbol_iterator symbol_end() { return Symbols.end(); } symbol_end()1101 const_symbol_iterator symbol_end() const { return Symbols.end(); } 1102 symbols()1103 symbol_range symbols() { return make_range(symbol_begin(), symbol_end()); } symbols()1104 const_symbol_range symbols() const { return make_range(symbol_begin(), symbol_end()); } 1105 symbol_size()1106 size_t symbol_size() const { return Symbols.size(); } 1107 1108 /// @} 1109 /// @name Indirect Symbol List Access 1110 /// @{ 1111 1112 // FIXME: This is a total hack, this should not be here. Once things are 1113 // factored so that the streamer has direct access to the .o writer, it can 1114 // disappear. getIndirectSymbols()1115 std::vector<IndirectSymbolData> &getIndirectSymbols() { 1116 return IndirectSymbols; 1117 } 1118 indirect_symbol_begin()1119 indirect_symbol_iterator indirect_symbol_begin() { 1120 return IndirectSymbols.begin(); 1121 } indirect_symbol_begin()1122 const_indirect_symbol_iterator indirect_symbol_begin() const { 1123 return IndirectSymbols.begin(); 1124 } 1125 indirect_symbol_end()1126 indirect_symbol_iterator indirect_symbol_end() { 1127 return IndirectSymbols.end(); 1128 } indirect_symbol_end()1129 const_indirect_symbol_iterator indirect_symbol_end() const { 1130 return IndirectSymbols.end(); 1131 } 1132 indirect_symbol_size()1133 size_t indirect_symbol_size() const { return IndirectSymbols.size(); } 1134 1135 /// @} 1136 /// @name Linker Option List Access 1137 /// @{ 1138 getLinkerOptions()1139 std::vector<std::vector<std::string> > &getLinkerOptions() { 1140 return LinkerOptions; 1141 } 1142 1143 /// @} 1144 /// @name Data Region List Access 1145 /// @{ 1146 1147 // FIXME: This is a total hack, this should not be here. Once things are 1148 // factored so that the streamer has direct access to the .o writer, it can 1149 // disappear. getDataRegions()1150 std::vector<DataRegionData> &getDataRegions() { 1151 return DataRegions; 1152 } 1153 data_region_begin()1154 data_region_iterator data_region_begin() { 1155 return DataRegions.begin(); 1156 } data_region_begin()1157 const_data_region_iterator data_region_begin() const { 1158 return DataRegions.begin(); 1159 } 1160 data_region_end()1161 data_region_iterator data_region_end() { 1162 return DataRegions.end(); 1163 } data_region_end()1164 const_data_region_iterator data_region_end() const { 1165 return DataRegions.end(); 1166 } 1167 data_region_size()1168 size_t data_region_size() const { return DataRegions.size(); } 1169 1170 /// @} 1171 /// @name Data Region List Access 1172 /// @{ 1173 1174 // FIXME: This is a total hack, this should not be here. Once things are 1175 // factored so that the streamer has direct access to the .o writer, it can 1176 // disappear. getLOHContainer()1177 MCLOHContainer & getLOHContainer() { 1178 return LOHContainer; 1179 } getLOHContainer()1180 const MCLOHContainer & getLOHContainer() const { 1181 return const_cast<MCAssembler *>(this)->getLOHContainer(); 1182 } 1183 /// @} 1184 /// @name Backend Data Access 1185 /// @{ 1186 getSectionData(const MCSection & Section)1187 MCSectionData &getSectionData(const MCSection &Section) const { 1188 MCSectionData *Entry = SectionMap.lookup(&Section); 1189 assert(Entry && "Missing section data!"); 1190 return *Entry; 1191 } 1192 1193 MCSectionData &getOrCreateSectionData(const MCSection &Section, 1194 bool *Created = nullptr) { 1195 MCSectionData *&Entry = SectionMap[&Section]; 1196 1197 if (Created) *Created = !Entry; 1198 if (!Entry) 1199 Entry = new MCSectionData(Section, this); 1200 1201 return *Entry; 1202 } 1203 hasSymbolData(const MCSymbol & Symbol)1204 bool hasSymbolData(const MCSymbol &Symbol) const { 1205 return SymbolMap.lookup(&Symbol) != nullptr; 1206 } 1207 getSymbolData(const MCSymbol & Symbol)1208 MCSymbolData &getSymbolData(const MCSymbol &Symbol) { 1209 return const_cast<MCSymbolData &>( 1210 static_cast<const MCAssembler &>(*this).getSymbolData(Symbol)); 1211 } 1212 getSymbolData(const MCSymbol & Symbol)1213 const MCSymbolData &getSymbolData(const MCSymbol &Symbol) const { 1214 MCSymbolData *Entry = SymbolMap.lookup(&Symbol); 1215 assert(Entry && "Missing symbol data!"); 1216 return *Entry; 1217 } 1218 1219 MCSymbolData &getOrCreateSymbolData(const MCSymbol &Symbol, 1220 bool *Created = nullptr) { 1221 MCSymbolData *&Entry = SymbolMap[&Symbol]; 1222 1223 if (Created) *Created = !Entry; 1224 if (!Entry) 1225 Entry = new MCSymbolData(Symbol, nullptr, 0, this); 1226 1227 return *Entry; 1228 } 1229 file_names_begin()1230 const_file_name_iterator file_names_begin() const { 1231 return FileNames.begin(); 1232 } 1233 file_names_end()1234 const_file_name_iterator file_names_end() const { 1235 return FileNames.end(); 1236 } 1237 addFileName(StringRef FileName)1238 void addFileName(StringRef FileName) { 1239 if (std::find(file_names_begin(), file_names_end(), FileName) == 1240 file_names_end()) 1241 FileNames.push_back(FileName); 1242 } 1243 1244 /// @} 1245 1246 void dump(); 1247 }; 1248 1249 } // end namespace llvm 1250 1251 #endif 1252