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