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