MCAssembler.h revision a94c33942373cb504b6e64c95415165907a89d34
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) 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) 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) 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 /// @} 594 595public: 596 // Only for use as sentinel. 597 MCSectionData(); 598 MCSectionData(const MCSection &Section, MCAssembler *A = 0); 599 600 const MCSection &getSection() const { return *Section; } 601 602 unsigned getAlignment() const { return Alignment; } 603 void setAlignment(unsigned Value) { Alignment = Value; } 604 605 bool hasInstructions() const { return HasInstructions; } 606 void setHasInstructions(bool Value) { HasInstructions = Value; } 607 608 unsigned getOrdinal() const { return Ordinal; } 609 void setOrdinal(unsigned Value) { Ordinal = Value; } 610 611 unsigned getLayoutOrder() const { return LayoutOrder; } 612 void setLayoutOrder(unsigned Value) { LayoutOrder = Value; } 613 614 /// @name Fragment Access 615 /// @{ 616 617 const FragmentListType &getFragmentList() const { return Fragments; } 618 FragmentListType &getFragmentList() { return Fragments; } 619 620 iterator begin() { return Fragments.begin(); } 621 const_iterator begin() const { return Fragments.begin(); } 622 623 iterator end() { return Fragments.end(); } 624 const_iterator end() const { return Fragments.end(); } 625 626 reverse_iterator rbegin() { return Fragments.rbegin(); } 627 const_reverse_iterator rbegin() const { return Fragments.rbegin(); } 628 629 reverse_iterator rend() { return Fragments.rend(); } 630 const_reverse_iterator rend() const { return Fragments.rend(); } 631 632 size_t size() const { return Fragments.size(); } 633 634 bool empty() const { return Fragments.empty(); } 635 636 bool isBundleLocked() const { 637 return BundleLockState != NotBundleLocked; 638 } 639 640 BundleLockStateType getBundleLockState() const { 641 return BundleLockState; 642 } 643 644 void setBundleLockState(BundleLockStateType NewState) { 645 BundleLockState = NewState; 646 } 647 648 bool isBundleGroupBeforeFirstInst() const { 649 return BundleGroupBeforeFirstInst; 650 } 651 652 void setBundleGroupBeforeFirstInst(bool IsFirst) { 653 BundleGroupBeforeFirstInst = IsFirst; 654 } 655 656 void dump(); 657 658 /// @} 659}; 660 661// FIXME: Same concerns as with SectionData. 662class MCSymbolData : public ilist_node<MCSymbolData> { 663public: 664 const MCSymbol *Symbol; 665 666 /// Fragment - The fragment this symbol's value is relative to, if any. 667 MCFragment *Fragment; 668 669 /// Offset - The offset to apply to the fragment address to form this symbol's 670 /// value. 671 uint64_t Offset; 672 673 /// IsExternal - True if this symbol is visible outside this translation 674 /// unit. 675 unsigned IsExternal : 1; 676 677 /// IsPrivateExtern - True if this symbol is private extern. 678 unsigned IsPrivateExtern : 1; 679 680 /// CommonSize - The size of the symbol, if it is 'common', or 0. 681 // 682 // FIXME: Pack this in with other fields? We could put it in offset, since a 683 // common symbol can never get a definition. 684 uint64_t CommonSize; 685 686 /// SymbolSize - An expression describing how to calculate the size of 687 /// a symbol. If a symbol has no size this field will be NULL. 688 const MCExpr *SymbolSize; 689 690 /// CommonAlign - The alignment of the symbol, if it is 'common'. 691 // 692 // FIXME: Pack this in with other fields? 693 unsigned CommonAlign; 694 695 /// Flags - The Flags field is used by object file implementations to store 696 /// additional per symbol information which is not easily classified. 697 uint32_t Flags; 698 699 /// Index - Index field, for use by the object file implementation. 700 uint64_t Index; 701 702public: 703 // Only for use as sentinel. 704 MCSymbolData(); 705 MCSymbolData(const MCSymbol &_Symbol, MCFragment *_Fragment, uint64_t _Offset, 706 MCAssembler *A = 0); 707 708 /// @name Accessors 709 /// @{ 710 711 const MCSymbol &getSymbol() const { return *Symbol; } 712 713 MCFragment *getFragment() const { return Fragment; } 714 void setFragment(MCFragment *Value) { Fragment = Value; } 715 716 uint64_t getOffset() const { return Offset; } 717 void setOffset(uint64_t Value) { Offset = Value; } 718 719 /// @} 720 /// @name Symbol Attributes 721 /// @{ 722 723 bool isExternal() const { return IsExternal; } 724 void setExternal(bool Value) { IsExternal = Value; } 725 726 bool isPrivateExtern() const { return IsPrivateExtern; } 727 void setPrivateExtern(bool Value) { IsPrivateExtern = Value; } 728 729 /// isCommon - Is this a 'common' symbol. 730 bool isCommon() const { return CommonSize != 0; } 731 732 /// setCommon - Mark this symbol as being 'common'. 733 /// 734 /// \param Size - The size of the symbol. 735 /// \param Align - The alignment of the symbol. 736 void setCommon(uint64_t Size, unsigned Align) { 737 CommonSize = Size; 738 CommonAlign = Align; 739 } 740 741 /// getCommonSize - Return the size of a 'common' symbol. 742 uint64_t getCommonSize() const { 743 assert(isCommon() && "Not a 'common' symbol!"); 744 return CommonSize; 745 } 746 747 void setSize(const MCExpr *SS) { 748 SymbolSize = SS; 749 } 750 751 const MCExpr *getSize() const { 752 return SymbolSize; 753 } 754 755 756 /// getCommonAlignment - Return the alignment of a 'common' symbol. 757 unsigned getCommonAlignment() const { 758 assert(isCommon() && "Not a 'common' symbol!"); 759 return CommonAlign; 760 } 761 762 /// getFlags - Get the (implementation defined) symbol flags. 763 uint32_t getFlags() const { return Flags; } 764 765 /// setFlags - Set the (implementation defined) symbol flags. 766 void setFlags(uint32_t Value) { Flags = Value; } 767 768 /// modifyFlags - Modify the flags via a mask 769 void modifyFlags(uint32_t Value, uint32_t Mask) { 770 Flags = (Flags & ~Mask) | Value; 771 } 772 773 /// getIndex - Get the (implementation defined) index. 774 uint64_t getIndex() const { return Index; } 775 776 /// setIndex - Set the (implementation defined) index. 777 void setIndex(uint64_t Value) { Index = Value; } 778 779 /// @} 780 781 void dump(); 782}; 783 784// FIXME: This really doesn't belong here. See comments below. 785struct IndirectSymbolData { 786 MCSymbol *Symbol; 787 MCSectionData *SectionData; 788}; 789 790// FIXME: Ditto this. Purely so the Streamer and the ObjectWriter can talk 791// to one another. 792struct DataRegionData { 793 // This enum should be kept in sync w/ the mach-o definition in 794 // llvm/Object/MachOFormat.h. 795 enum KindTy { Data = 1, JumpTable8, JumpTable16, JumpTable32 } Kind; 796 MCSymbol *Start; 797 MCSymbol *End; 798}; 799 800class MCAssembler { 801 friend class MCAsmLayout; 802 803public: 804 typedef iplist<MCSectionData> SectionDataListType; 805 typedef iplist<MCSymbolData> SymbolDataListType; 806 807 typedef SectionDataListType::const_iterator const_iterator; 808 typedef SectionDataListType::iterator iterator; 809 810 typedef SymbolDataListType::const_iterator const_symbol_iterator; 811 typedef SymbolDataListType::iterator symbol_iterator; 812 813 typedef std::vector<IndirectSymbolData>::const_iterator 814 const_indirect_symbol_iterator; 815 typedef std::vector<IndirectSymbolData>::iterator indirect_symbol_iterator; 816 817 typedef std::vector<DataRegionData>::const_iterator 818 const_data_region_iterator; 819 typedef std::vector<DataRegionData>::iterator data_region_iterator; 820 821private: 822 MCAssembler(const MCAssembler&) LLVM_DELETED_FUNCTION; 823 void operator=(const MCAssembler&) LLVM_DELETED_FUNCTION; 824 825 MCContext &Context; 826 827 MCAsmBackend &Backend; 828 829 MCCodeEmitter &Emitter; 830 831 MCObjectWriter &Writer; 832 833 raw_ostream &OS; 834 835 iplist<MCSectionData> Sections; 836 837 iplist<MCSymbolData> Symbols; 838 839 /// The map of sections to their associated assembler backend data. 840 // 841 // FIXME: Avoid this indirection? 842 DenseMap<const MCSection*, MCSectionData*> SectionMap; 843 844 /// The map of symbols to their associated assembler backend data. 845 // 846 // FIXME: Avoid this indirection? 847 DenseMap<const MCSymbol*, MCSymbolData*> SymbolMap; 848 849 std::vector<IndirectSymbolData> IndirectSymbols; 850 851 std::vector<DataRegionData> DataRegions; 852 853 /// The list of linker options to propagate into the object file. 854 std::vector<std::vector<std::string> > LinkerOptions; 855 856 /// The set of function symbols for which a .thumb_func directive has 857 /// been seen. 858 // 859 // FIXME: We really would like this in target specific code rather than 860 // here. Maybe when the relocation stuff moves to target specific, 861 // this can go with it? The streamer would need some target specific 862 // refactoring too. 863 SmallPtrSet<const MCSymbol*, 64> ThumbFuncs; 864 865 /// \brief The bundle alignment size currently set in the assembler. 866 /// 867 /// By default it's 0, which means bundling is disabled. 868 unsigned BundleAlignSize; 869 870 unsigned RelaxAll : 1; 871 unsigned NoExecStack : 1; 872 unsigned SubsectionsViaSymbols : 1; 873 874private: 875 /// Evaluate a fixup to a relocatable expression and the value which should be 876 /// placed into the fixup. 877 /// 878 /// \param Layout The layout to use for evaluation. 879 /// \param Fixup The fixup to evaluate. 880 /// \param DF The fragment the fixup is inside. 881 /// \param Target [out] On return, the relocatable expression the fixup 882 /// evaluates to. 883 /// \param Value [out] On return, the value of the fixup as currently laid 884 /// out. 885 /// \return Whether the fixup value was fully resolved. This is true if the 886 /// \p Value result is fixed, otherwise the value may change due to 887 /// relocation. 888 bool evaluateFixup(const MCAsmLayout &Layout, 889 const MCFixup &Fixup, const MCFragment *DF, 890 MCValue &Target, uint64_t &Value) const; 891 892 /// Check whether a fixup can be satisfied, or whether it needs to be relaxed 893 /// (increased in size, in order to hold its value correctly). 894 bool fixupNeedsRelaxation(const MCFixup &Fixup, const MCRelaxableFragment *DF, 895 const MCAsmLayout &Layout) const; 896 897 /// Check whether the given fragment needs relaxation. 898 bool fragmentNeedsRelaxation(const MCRelaxableFragment *IF, 899 const MCAsmLayout &Layout) const; 900 901 /// \brief Perform one layout iteration and return true if any offsets 902 /// were adjusted. 903 bool layoutOnce(MCAsmLayout &Layout); 904 905 /// \brief Perform one layout iteration of the given section and return true 906 /// if any offsets were adjusted. 907 bool layoutSectionOnce(MCAsmLayout &Layout, MCSectionData &SD); 908 909 bool relaxInstruction(MCAsmLayout &Layout, MCRelaxableFragment &IF); 910 911 bool relaxLEB(MCAsmLayout &Layout, MCLEBFragment &IF); 912 913 bool relaxDwarfLineAddr(MCAsmLayout &Layout, MCDwarfLineAddrFragment &DF); 914 bool relaxDwarfCallFrameFragment(MCAsmLayout &Layout, 915 MCDwarfCallFrameFragment &DF); 916 917 /// finishLayout - Finalize a layout, including fragment lowering. 918 void finishLayout(MCAsmLayout &Layout); 919 920 uint64_t handleFixup(const MCAsmLayout &Layout, 921 MCFragment &F, const MCFixup &Fixup); 922 923public: 924 /// Compute the effective fragment size assuming it is laid out at the given 925 /// \p SectionAddress and \p FragmentOffset. 926 uint64_t computeFragmentSize(const MCAsmLayout &Layout, 927 const MCFragment &F) const; 928 929 /// Find the symbol which defines the atom containing the given symbol, or 930 /// null if there is no such symbol. 931 const MCSymbolData *getAtom(const MCSymbolData *Symbol) const; 932 933 /// Check whether a particular symbol is visible to the linker and is required 934 /// in the symbol table, or whether it can be discarded by the assembler. This 935 /// also effects whether the assembler treats the label as potentially 936 /// defining a separate atom. 937 bool isSymbolLinkerVisible(const MCSymbol &SD) const; 938 939 /// Emit the section contents using the given object writer. 940 void writeSectionData(const MCSectionData *Section, 941 const MCAsmLayout &Layout) const; 942 943 /// Check whether a given symbol has been flagged with .thumb_func. 944 bool isThumbFunc(const MCSymbol *Func) const { 945 return ThumbFuncs.count(Func); 946 } 947 948 /// Flag a function symbol as the target of a .thumb_func directive. 949 void setIsThumbFunc(const MCSymbol *Func) { ThumbFuncs.insert(Func); } 950 951public: 952 /// Construct a new assembler instance. 953 /// 954 /// \param OS The stream to output to. 955 // 956 // FIXME: How are we going to parameterize this? Two obvious options are stay 957 // concrete and require clients to pass in a target like object. The other 958 // option is to make this abstract, and have targets provide concrete 959 // implementations as we do with AsmParser. 960 MCAssembler(MCContext &Context_, MCAsmBackend &Backend_, 961 MCCodeEmitter &Emitter_, MCObjectWriter &Writer_, 962 raw_ostream &OS); 963 ~MCAssembler(); 964 965 /// Reuse an assembler instance 966 /// 967 void reset(); 968 969 MCContext &getContext() const { return Context; } 970 971 MCAsmBackend &getBackend() const { return Backend; } 972 973 MCCodeEmitter &getEmitter() const { return Emitter; } 974 975 MCObjectWriter &getWriter() const { return Writer; } 976 977 /// Finish - Do final processing and write the object to the output stream. 978 /// \p Writer is used for custom object writer (as the MCJIT does), 979 /// if not specified it is automatically created from backend. 980 void Finish(); 981 982 // FIXME: This does not belong here. 983 bool getSubsectionsViaSymbols() const { 984 return SubsectionsViaSymbols; 985 } 986 void setSubsectionsViaSymbols(bool Value) { 987 SubsectionsViaSymbols = Value; 988 } 989 990 bool getRelaxAll() const { return RelaxAll; } 991 void setRelaxAll(bool Value) { RelaxAll = Value; } 992 993 bool getNoExecStack() const { return NoExecStack; } 994 void setNoExecStack(bool Value) { NoExecStack = Value; } 995 996 bool isBundlingEnabled() const { 997 return BundleAlignSize != 0; 998 } 999 1000 unsigned getBundleAlignSize() const { 1001 return BundleAlignSize; 1002 } 1003 1004 void setBundleAlignSize(unsigned Size) { 1005 assert((Size == 0 || !(Size & (Size - 1))) && 1006 "Expect a power-of-two bundle align size"); 1007 BundleAlignSize = Size; 1008 } 1009 1010 /// @name Section List Access 1011 /// @{ 1012 1013 const SectionDataListType &getSectionList() const { return Sections; } 1014 SectionDataListType &getSectionList() { return Sections; } 1015 1016 iterator begin() { return Sections.begin(); } 1017 const_iterator begin() const { return Sections.begin(); } 1018 1019 iterator end() { return Sections.end(); } 1020 const_iterator end() const { return Sections.end(); } 1021 1022 size_t size() const { return Sections.size(); } 1023 1024 /// @} 1025 /// @name Symbol List Access 1026 /// @{ 1027 1028 const SymbolDataListType &getSymbolList() const { return Symbols; } 1029 SymbolDataListType &getSymbolList() { return Symbols; } 1030 1031 symbol_iterator symbol_begin() { return Symbols.begin(); } 1032 const_symbol_iterator symbol_begin() const { return Symbols.begin(); } 1033 1034 symbol_iterator symbol_end() { return Symbols.end(); } 1035 const_symbol_iterator symbol_end() const { return Symbols.end(); } 1036 1037 size_t symbol_size() const { return Symbols.size(); } 1038 1039 /// @} 1040 /// @name Indirect Symbol List Access 1041 /// @{ 1042 1043 // FIXME: This is a total hack, this should not be here. Once things are 1044 // factored so that the streamer has direct access to the .o writer, it can 1045 // disappear. 1046 std::vector<IndirectSymbolData> &getIndirectSymbols() { 1047 return IndirectSymbols; 1048 } 1049 1050 indirect_symbol_iterator indirect_symbol_begin() { 1051 return IndirectSymbols.begin(); 1052 } 1053 const_indirect_symbol_iterator indirect_symbol_begin() const { 1054 return IndirectSymbols.begin(); 1055 } 1056 1057 indirect_symbol_iterator indirect_symbol_end() { 1058 return IndirectSymbols.end(); 1059 } 1060 const_indirect_symbol_iterator indirect_symbol_end() const { 1061 return IndirectSymbols.end(); 1062 } 1063 1064 size_t indirect_symbol_size() const { return IndirectSymbols.size(); } 1065 1066 /// @} 1067 /// @name Linker Option List Access 1068 /// @{ 1069 1070 std::vector<std::vector<std::string> > &getLinkerOptions() { 1071 return LinkerOptions; 1072 } 1073 1074 /// @} 1075 /// @name Data Region List Access 1076 /// @{ 1077 1078 // FIXME: This is a total hack, this should not be here. Once things are 1079 // factored so that the streamer has direct access to the .o writer, it can 1080 // disappear. 1081 std::vector<DataRegionData> &getDataRegions() { 1082 return DataRegions; 1083 } 1084 1085 data_region_iterator data_region_begin() { 1086 return DataRegions.begin(); 1087 } 1088 const_data_region_iterator data_region_begin() const { 1089 return DataRegions.begin(); 1090 } 1091 1092 data_region_iterator data_region_end() { 1093 return DataRegions.end(); 1094 } 1095 const_data_region_iterator data_region_end() const { 1096 return DataRegions.end(); 1097 } 1098 1099 size_t data_region_size() const { return DataRegions.size(); } 1100 1101 /// @} 1102 /// @name Backend Data Access 1103 /// @{ 1104 1105 MCSectionData &getSectionData(const MCSection &Section) const { 1106 MCSectionData *Entry = SectionMap.lookup(&Section); 1107 assert(Entry && "Missing section data!"); 1108 return *Entry; 1109 } 1110 1111 MCSectionData &getOrCreateSectionData(const MCSection &Section, 1112 bool *Created = 0) { 1113 MCSectionData *&Entry = SectionMap[&Section]; 1114 1115 if (Created) *Created = !Entry; 1116 if (!Entry) 1117 Entry = new MCSectionData(Section, this); 1118 1119 return *Entry; 1120 } 1121 1122 MCSymbolData &getSymbolData(const MCSymbol &Symbol) const { 1123 MCSymbolData *Entry = SymbolMap.lookup(&Symbol); 1124 assert(Entry && "Missing symbol data!"); 1125 return *Entry; 1126 } 1127 1128 MCSymbolData &getOrCreateSymbolData(const MCSymbol &Symbol, 1129 bool *Created = 0) { 1130 MCSymbolData *&Entry = SymbolMap[&Symbol]; 1131 1132 if (Created) *Created = !Entry; 1133 if (!Entry) 1134 Entry = new MCSymbolData(Symbol, 0, 0, this); 1135 1136 return *Entry; 1137 } 1138 1139 /// @} 1140 1141 void dump(); 1142}; 1143 1144} // end namespace llvm 1145 1146#endif 1147