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