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