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