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