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