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/MC/MCFixup.h" 14 #include "llvm/MC/MCInst.h" 15 #include "llvm/ADT/DenseMap.h" 16 #include "llvm/ADT/SmallPtrSet.h" 17 #include "llvm/ADT/SmallString.h" 18 #include "llvm/ADT/ilist.h" 19 #include "llvm/ADT/ilist_node.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&); // DO NOT IMPLEMENT 49 void operator=(const MCFragment&); // DO NOT IMPLEMENT 50 51 public: 52 enum FragmentType { 53 FT_Align, 54 FT_Data, 55 FT_Fill, 56 FT_Inst, 57 FT_Org, 58 FT_Dwarf, 59 FT_DwarfFrame, 60 FT_LEB, 61 FT_Region, 62 FT_Reloc, 63 FT_Target 64 }; 65 66 private: 67 FragmentType Kind; 68 69 /// Parent - The data for the section this fragment is in. 70 MCSectionData *Parent; 71 72 /// Atom - The atom this fragment is in, as represented by it's defining 73 /// symbol. Atom's are only used by backends which set 74 /// \see MCAsmBackend::hasReliableSymbolDifference(). 75 MCSymbolData *Atom; 76 77 /// @name Assembler Backend Data 78 /// @{ 79 // 80 // FIXME: This could all be kept private to the assembler implementation. 81 82 /// Offset - The offset of this fragment in its section. This is ~0 until 83 /// initialized. 84 uint64_t Offset; 85 86 /// LayoutOrder - The layout order of this fragment. 87 unsigned LayoutOrder; 88 89 /// @} 90 91 protected: 92 MCFragment(FragmentType _Kind, MCSectionData *_Parent = 0); 93 94 public: 95 // Only for sentinel. 96 MCFragment(); 97 virtual ~MCFragment(); 98 99 FragmentType getKind() const { return Kind; } 100 101 MCSectionData *getParent() const { return Parent; } 102 void setParent(MCSectionData *Value) { Parent = Value; } 103 104 MCSymbolData *getAtom() const { return Atom; } 105 void setAtom(MCSymbolData *Value) { Atom = Value; } 106 107 unsigned getLayoutOrder() const { return LayoutOrder; } 108 void setLayoutOrder(unsigned Value) { LayoutOrder = Value; } 109 110 static bool classof(const MCFragment *O) { return true; } 111 112 void dump(); 113 }; 114 115 class MCDataFragment : public MCFragment { 116 virtual void anchor(); 117 SmallString<32> Contents; 118 119 /// Fixups - The list of fixups in this fragment. 120 std::vector<MCFixup> Fixups; 121 122 public: 123 typedef std::vector<MCFixup>::const_iterator const_fixup_iterator; 124 typedef std::vector<MCFixup>::iterator fixup_iterator; 125 126 public: 127 MCDataFragment(MCSectionData *SD = 0) : MCFragment(FT_Data, SD) {} 128 129 /// @name Accessors 130 /// @{ 131 132 SmallString<32> &getContents() { return Contents; } 133 const SmallString<32> &getContents() const { return Contents; } 134 135 /// @} 136 /// @name Fixup Access 137 /// @{ 138 139 void addFixup(MCFixup Fixup) { 140 // Enforce invariant that fixups are in offset order. 141 assert((Fixups.empty() || Fixup.getOffset() > Fixups.back().getOffset()) && 142 "Fixups must be added in order!"); 143 Fixups.push_back(Fixup); 144 } 145 146 std::vector<MCFixup> &getFixups() { return Fixups; } 147 const std::vector<MCFixup> &getFixups() const { return Fixups; } 148 149 fixup_iterator fixup_begin() { return Fixups.begin(); } 150 const_fixup_iterator fixup_begin() const { return Fixups.begin(); } 151 152 fixup_iterator fixup_end() {return Fixups.end();} 153 const_fixup_iterator fixup_end() const {return Fixups.end();} 154 155 size_t fixup_size() const { return Fixups.size(); } 156 157 /// @} 158 159 static bool classof(const MCFragment *F) { 160 return F->getKind() == MCFragment::FT_Data; 161 } 162 static bool classof(const MCDataFragment *) { return true; } 163 }; 164 165 // FIXME: This current incarnation of MCInstFragment doesn't make much sense, as 166 // it is almost entirely a duplicate of MCDataFragment. If we decide to stick 167 // with this approach (as opposed to making MCInstFragment a very light weight 168 // object with just the MCInst and a code size, then we should just change 169 // MCDataFragment to have an optional MCInst at its end. 170 class MCInstFragment : public MCFragment { 171 virtual void anchor(); 172 173 /// Inst - The instruction this is a fragment for. 174 MCInst Inst; 175 176 /// Code - Binary data for the currently encoded instruction. 177 SmallString<8> Code; 178 179 /// Fixups - The list of fixups in this fragment. 180 SmallVector<MCFixup, 1> Fixups; 181 182 public: 183 typedef SmallVectorImpl<MCFixup>::const_iterator const_fixup_iterator; 184 typedef SmallVectorImpl<MCFixup>::iterator fixup_iterator; 185 186 public: 187 MCInstFragment(MCInst _Inst, MCSectionData *SD = 0) 188 : MCFragment(FT_Inst, SD), Inst(_Inst) { 189 } 190 191 /// @name Accessors 192 /// @{ 193 194 SmallVectorImpl<char> &getCode() { return Code; } 195 const SmallVectorImpl<char> &getCode() const { return Code; } 196 197 unsigned getInstSize() const { return Code.size(); } 198 199 MCInst &getInst() { return Inst; } 200 const MCInst &getInst() const { return Inst; } 201 202 void setInst(MCInst Value) { Inst = Value; } 203 204 /// @} 205 /// @name Fixup Access 206 /// @{ 207 208 SmallVectorImpl<MCFixup> &getFixups() { return Fixups; } 209 const SmallVectorImpl<MCFixup> &getFixups() const { return Fixups; } 210 211 fixup_iterator fixup_begin() { return Fixups.begin(); } 212 const_fixup_iterator fixup_begin() const { return Fixups.begin(); } 213 214 fixup_iterator fixup_end() {return Fixups.end();} 215 const_fixup_iterator fixup_end() const {return Fixups.end();} 216 217 size_t fixup_size() const { return Fixups.size(); } 218 219 /// @} 220 221 static bool classof(const MCFragment *F) { 222 return F->getKind() == MCFragment::FT_Inst; 223 } 224 static bool classof(const MCInstFragment *) { return true; } 225 }; 226 227 class MCAlignFragment : public MCFragment { 228 virtual void anchor(); 229 230 /// Alignment - The alignment to ensure, in bytes. 231 unsigned Alignment; 232 233 /// Value - Value to use for filling padding bytes. 234 int64_t Value; 235 236 /// ValueSize - The size of the integer (in bytes) of \arg Value. 237 unsigned ValueSize; 238 239 /// MaxBytesToEmit - The maximum number of bytes to emit; if the alignment 240 /// cannot be satisfied in this width then this fragment is ignored. 241 unsigned MaxBytesToEmit; 242 243 /// EmitNops - Flag to indicate that (optimal) NOPs should be emitted instead 244 /// of using the provided value. The exact interpretation of this flag is 245 /// target dependent. 246 bool EmitNops : 1; 247 248 public: 249 MCAlignFragment(unsigned _Alignment, int64_t _Value, unsigned _ValueSize, 250 unsigned _MaxBytesToEmit, MCSectionData *SD = 0) 251 : MCFragment(FT_Align, SD), Alignment(_Alignment), 252 Value(_Value),ValueSize(_ValueSize), 253 MaxBytesToEmit(_MaxBytesToEmit), EmitNops(false) {} 254 255 /// @name Accessors 256 /// @{ 257 258 unsigned getAlignment() const { return Alignment; } 259 260 int64_t getValue() const { return Value; } 261 262 unsigned getValueSize() const { return ValueSize; } 263 264 unsigned getMaxBytesToEmit() const { return MaxBytesToEmit; } 265 266 bool hasEmitNops() const { return EmitNops; } 267 void setEmitNops(bool Value) { EmitNops = Value; } 268 269 /// @} 270 271 static bool classof(const MCFragment *F) { 272 return F->getKind() == MCFragment::FT_Align; 273 } 274 static bool classof(const MCAlignFragment *) { return true; } 275 }; 276 277 class MCFillFragment : public MCFragment { 278 virtual void anchor(); 279 280 /// Value - Value to use for filling bytes. 281 int64_t Value; 282 283 /// ValueSize - The size (in bytes) of \arg Value to use when filling, or 0 if 284 /// this is a virtual fill fragment. 285 unsigned ValueSize; 286 287 /// Size - The number of bytes to insert. 288 uint64_t Size; 289 290 public: 291 MCFillFragment(int64_t _Value, unsigned _ValueSize, uint64_t _Size, 292 MCSectionData *SD = 0) 293 : MCFragment(FT_Fill, SD), 294 Value(_Value), ValueSize(_ValueSize), Size(_Size) { 295 assert((!ValueSize || (Size % ValueSize) == 0) && 296 "Fill size must be a multiple of the value size!"); 297 } 298 299 /// @name Accessors 300 /// @{ 301 302 int64_t getValue() const { return Value; } 303 304 unsigned getValueSize() const { return ValueSize; } 305 306 uint64_t getSize() const { return Size; } 307 308 /// @} 309 310 static bool classof(const MCFragment *F) { 311 return F->getKind() == MCFragment::FT_Fill; 312 } 313 static bool classof(const MCFillFragment *) { return true; } 314 }; 315 316 class MCOrgFragment : public MCFragment { 317 virtual void anchor(); 318 319 /// Offset - The offset this fragment should start at. 320 const MCExpr *Offset; 321 322 /// Value - Value to use for filling bytes. 323 int8_t Value; 324 325 public: 326 MCOrgFragment(const MCExpr &_Offset, int8_t _Value, MCSectionData *SD = 0) 327 : MCFragment(FT_Org, SD), 328 Offset(&_Offset), Value(_Value) {} 329 330 /// @name Accessors 331 /// @{ 332 333 const MCExpr &getOffset() const { return *Offset; } 334 335 uint8_t getValue() const { return Value; } 336 337 /// @} 338 339 static bool classof(const MCFragment *F) { 340 return F->getKind() == MCFragment::FT_Org; 341 } 342 static bool classof(const MCOrgFragment *) { return true; } 343 }; 344 345 class MCLEBFragment : public MCFragment { 346 virtual void anchor(); 347 348 /// Value - The value this fragment should contain. 349 const MCExpr *Value; 350 351 /// IsSigned - True if this is a sleb128, false if uleb128. 352 bool IsSigned; 353 354 SmallString<8> Contents; 355 public: 356 MCLEBFragment(const MCExpr &Value_, bool IsSigned_, MCSectionData *SD) 357 : MCFragment(FT_LEB, SD), 358 Value(&Value_), IsSigned(IsSigned_) { Contents.push_back(0); } 359 360 /// @name Accessors 361 /// @{ 362 363 const MCExpr &getValue() const { return *Value; } 364 365 bool isSigned() const { return IsSigned; } 366 367 SmallString<8> &getContents() { return Contents; } 368 const SmallString<8> &getContents() const { return Contents; } 369 370 /// @} 371 372 static bool classof(const MCFragment *F) { 373 return F->getKind() == MCFragment::FT_LEB; 374 } 375 static bool classof(const MCLEBFragment *) { return true; } 376 }; 377 378 class MCDwarfLineAddrFragment : public MCFragment { 379 virtual void anchor(); 380 381 /// LineDelta - the value of the difference between the two line numbers 382 /// between two .loc dwarf directives. 383 int64_t LineDelta; 384 385 /// AddrDelta - The expression for the difference of the two symbols that 386 /// make up the address delta between two .loc dwarf directives. 387 const MCExpr *AddrDelta; 388 389 SmallString<8> Contents; 390 391 public: 392 MCDwarfLineAddrFragment(int64_t _LineDelta, const MCExpr &_AddrDelta, 393 MCSectionData *SD) 394 : MCFragment(FT_Dwarf, SD), 395 LineDelta(_LineDelta), AddrDelta(&_AddrDelta) { Contents.push_back(0); } 396 397 /// @name Accessors 398 /// @{ 399 400 int64_t getLineDelta() const { return LineDelta; } 401 402 const MCExpr &getAddrDelta() const { return *AddrDelta; } 403 404 SmallString<8> &getContents() { return Contents; } 405 const SmallString<8> &getContents() const { return Contents; } 406 407 /// @} 408 409 static bool classof(const MCFragment *F) { 410 return F->getKind() == MCFragment::FT_Dwarf; 411 } 412 static bool classof(const MCDwarfLineAddrFragment *) { return true; } 413 }; 414 415 class MCDwarfCallFrameFragment : public MCFragment { 416 virtual void anchor(); 417 418 /// AddrDelta - The expression for the difference of the two symbols that 419 /// make up the address delta between two .cfi_* dwarf directives. 420 const MCExpr *AddrDelta; 421 422 SmallString<8> Contents; 423 424 public: 425 MCDwarfCallFrameFragment(const MCExpr &_AddrDelta, MCSectionData *SD) 426 : MCFragment(FT_DwarfFrame, SD), 427 AddrDelta(&_AddrDelta) { Contents.push_back(0); } 428 429 /// @name Accessors 430 /// @{ 431 432 const MCExpr &getAddrDelta() const { return *AddrDelta; } 433 434 SmallString<8> &getContents() { return Contents; } 435 const SmallString<8> &getContents() const { return Contents; } 436 437 /// @} 438 439 static bool classof(const MCFragment *F) { 440 return F->getKind() == MCFragment::FT_DwarfFrame; 441 } 442 static bool classof(const MCDwarfCallFrameFragment *) { return true; } 443 }; 444 445 // FIXME: Should this be a separate class, or just merged into MCSection? Since 446 // we anticipate the fast path being through an MCAssembler, the only reason to 447 // keep it out is for API abstraction. 448 class MCSectionData : public ilist_node<MCSectionData> { 449 friend class MCAsmLayout; 450 451 MCSectionData(const MCSectionData&); // DO NOT IMPLEMENT 452 void operator=(const MCSectionData&); // DO NOT IMPLEMENT 453 454 public: 455 typedef iplist<MCFragment> FragmentListType; 456 457 typedef FragmentListType::const_iterator const_iterator; 458 typedef FragmentListType::iterator iterator; 459 460 typedef FragmentListType::const_reverse_iterator const_reverse_iterator; 461 typedef FragmentListType::reverse_iterator reverse_iterator; 462 463 private: 464 FragmentListType Fragments; 465 const MCSection *Section; 466 467 /// Ordinal - The section index in the assemblers section list. 468 unsigned Ordinal; 469 470 /// LayoutOrder - The index of this section in the layout order. 471 unsigned LayoutOrder; 472 473 /// Alignment - The maximum alignment seen in this section. 474 unsigned Alignment; 475 476 /// @name Assembler Backend Data 477 /// @{ 478 // 479 // FIXME: This could all be kept private to the assembler implementation. 480 481 /// HasInstructions - Whether this section has had instructions emitted into 482 /// it. 483 unsigned HasInstructions : 1; 484 485 /// @} 486 487 public: 488 // Only for use as sentinel. 489 MCSectionData(); 490 MCSectionData(const MCSection &Section, MCAssembler *A = 0); 491 492 const MCSection &getSection() const { return *Section; } 493 494 unsigned getAlignment() const { return Alignment; } 495 void setAlignment(unsigned Value) { Alignment = Value; } 496 497 bool hasInstructions() const { return HasInstructions; } 498 void setHasInstructions(bool Value) { HasInstructions = Value; } 499 500 unsigned getOrdinal() const { return Ordinal; } 501 void setOrdinal(unsigned Value) { Ordinal = Value; } 502 503 unsigned getLayoutOrder() const { return LayoutOrder; } 504 void setLayoutOrder(unsigned Value) { LayoutOrder = Value; } 505 506 /// @name Fragment Access 507 /// @{ 508 509 const FragmentListType &getFragmentList() const { return Fragments; } 510 FragmentListType &getFragmentList() { return Fragments; } 511 512 iterator begin() { return Fragments.begin(); } 513 const_iterator begin() const { return Fragments.begin(); } 514 515 iterator end() { return Fragments.end(); } 516 const_iterator end() const { return Fragments.end(); } 517 518 reverse_iterator rbegin() { return Fragments.rbegin(); } 519 const_reverse_iterator rbegin() const { return Fragments.rbegin(); } 520 521 reverse_iterator rend() { return Fragments.rend(); } 522 const_reverse_iterator rend() const { return Fragments.rend(); } 523 524 size_t size() const { return Fragments.size(); } 525 526 bool empty() const { return Fragments.empty(); } 527 528 void dump(); 529 530 /// @} 531 }; 532 533 // FIXME: Same concerns as with SectionData. 534 class MCSymbolData : public ilist_node<MCSymbolData> { 535 public: 536 const MCSymbol *Symbol; 537 538 /// Fragment - The fragment this symbol's value is relative to, if any. 539 MCFragment *Fragment; 540 541 /// Offset - The offset to apply to the fragment address to form this symbol's 542 /// value. 543 uint64_t Offset; 544 545 /// IsExternal - True if this symbol is visible outside this translation 546 /// unit. 547 unsigned IsExternal : 1; 548 549 /// IsPrivateExtern - True if this symbol is private extern. 550 unsigned IsPrivateExtern : 1; 551 552 /// CommonSize - The size of the symbol, if it is 'common', or 0. 553 // 554 // FIXME: Pack this in with other fields? We could put it in offset, since a 555 // common symbol can never get a definition. 556 uint64_t CommonSize; 557 558 /// SymbolSize - An expression describing how to calculate the size of 559 /// a symbol. If a symbol has no size this field will be NULL. 560 const MCExpr *SymbolSize; 561 562 /// CommonAlign - The alignment of the symbol, if it is 'common'. 563 // 564 // FIXME: Pack this in with other fields? 565 unsigned CommonAlign; 566 567 /// Flags - The Flags field is used by object file implementations to store 568 /// additional per symbol information which is not easily classified. 569 uint32_t Flags; 570 571 /// Index - Index field, for use by the object file implementation. 572 uint64_t Index; 573 574 public: 575 // Only for use as sentinel. 576 MCSymbolData(); 577 MCSymbolData(const MCSymbol &_Symbol, MCFragment *_Fragment, uint64_t _Offset, 578 MCAssembler *A = 0); 579 580 /// @name Accessors 581 /// @{ 582 583 const MCSymbol &getSymbol() const { return *Symbol; } 584 585 MCFragment *getFragment() const { return Fragment; } 586 void setFragment(MCFragment *Value) { Fragment = Value; } 587 588 uint64_t getOffset() const { return Offset; } 589 void setOffset(uint64_t Value) { Offset = Value; } 590 591 /// @} 592 /// @name Symbol Attributes 593 /// @{ 594 595 bool isExternal() const { return IsExternal; } 596 void setExternal(bool Value) { IsExternal = Value; } 597 598 bool isPrivateExtern() const { return IsPrivateExtern; } 599 void setPrivateExtern(bool Value) { IsPrivateExtern = Value; } 600 601 /// isCommon - Is this a 'common' symbol. 602 bool isCommon() const { return CommonSize != 0; } 603 604 /// setCommon - Mark this symbol as being 'common'. 605 /// 606 /// \param Size - The size of the symbol. 607 /// \param Align - The alignment of the symbol. 608 void setCommon(uint64_t Size, unsigned Align) { 609 CommonSize = Size; 610 CommonAlign = Align; 611 } 612 613 /// getCommonSize - Return the size of a 'common' symbol. 614 uint64_t getCommonSize() const { 615 assert(isCommon() && "Not a 'common' symbol!"); 616 return CommonSize; 617 } 618 619 void setSize(const MCExpr *SS) { 620 SymbolSize = SS; 621 } 622 623 const MCExpr *getSize() const { 624 return SymbolSize; 625 } 626 627 628 /// getCommonAlignment - Return the alignment of a 'common' symbol. 629 unsigned getCommonAlignment() const { 630 assert(isCommon() && "Not a 'common' symbol!"); 631 return CommonAlign; 632 } 633 634 /// getFlags - Get the (implementation defined) symbol flags. 635 uint32_t getFlags() const { return Flags; } 636 637 /// setFlags - Set the (implementation defined) symbol flags. 638 void setFlags(uint32_t Value) { Flags = Value; } 639 640 /// modifyFlags - Modify the flags via a mask 641 void modifyFlags(uint32_t Value, uint32_t Mask) { 642 Flags = (Flags & ~Mask) | Value; 643 } 644 645 /// getIndex - Get the (implementation defined) index. 646 uint64_t getIndex() const { return Index; } 647 648 /// setIndex - Set the (implementation defined) index. 649 void setIndex(uint64_t Value) { Index = Value; } 650 651 /// @} 652 653 void dump(); 654 }; 655 656 // FIXME: This really doesn't belong here. See comments below. 657 struct IndirectSymbolData { 658 MCSymbol *Symbol; 659 MCSectionData *SectionData; 660 }; 661 662 class MCAssembler { 663 friend class MCAsmLayout; 664 665 public: 666 typedef iplist<MCSectionData> SectionDataListType; 667 typedef iplist<MCSymbolData> SymbolDataListType; 668 669 typedef SectionDataListType::const_iterator const_iterator; 670 typedef SectionDataListType::iterator iterator; 671 672 typedef SymbolDataListType::const_iterator const_symbol_iterator; 673 typedef SymbolDataListType::iterator symbol_iterator; 674 675 typedef std::vector<IndirectSymbolData>::const_iterator 676 const_indirect_symbol_iterator; 677 typedef std::vector<IndirectSymbolData>::iterator indirect_symbol_iterator; 678 679 private: 680 MCAssembler(const MCAssembler&); // DO NOT IMPLEMENT 681 void operator=(const MCAssembler&); // DO NOT IMPLEMENT 682 683 MCContext &Context; 684 685 MCAsmBackend &Backend; 686 687 MCCodeEmitter &Emitter; 688 689 MCObjectWriter *Writer; 690 691 raw_ostream &OS; 692 693 iplist<MCSectionData> Sections; 694 695 iplist<MCSymbolData> Symbols; 696 697 /// The map of sections to their associated assembler backend data. 698 // 699 // FIXME: Avoid this indirection? 700 DenseMap<const MCSection*, MCSectionData*> SectionMap; 701 702 /// The map of symbols to their associated assembler backend data. 703 // 704 // FIXME: Avoid this indirection? 705 DenseMap<const MCSymbol*, MCSymbolData*> SymbolMap; 706 707 std::vector<IndirectSymbolData> IndirectSymbols; 708 709 /// The set of function symbols for which a .thumb_func directive has 710 /// been seen. 711 // 712 // FIXME: We really would like this in target specific code rather than 713 // here. Maybe when the relocation stuff moves to target specific, 714 // this can go with it? The streamer would need some target specific 715 // refactoring too. 716 SmallPtrSet<const MCSymbol*, 64> ThumbFuncs; 717 718 unsigned RelaxAll : 1; 719 unsigned NoExecStack : 1; 720 unsigned SubsectionsViaSymbols : 1; 721 722 private: 723 /// Evaluate a fixup to a relocatable expression and the value which should be 724 /// placed into the fixup. 725 /// 726 /// \param Layout The layout to use for evaluation. 727 /// \param Fixup The fixup to evaluate. 728 /// \param DF The fragment the fixup is inside. 729 /// \param Target [out] On return, the relocatable expression the fixup 730 /// evaluates to. 731 /// \param Value [out] On return, the value of the fixup as currently laid 732 /// out. 733 /// \return Whether the fixup value was fully resolved. This is true if the 734 /// \arg Value result is fixed, otherwise the value may change due to 735 /// relocation. 736 bool evaluateFixup(const MCAsmLayout &Layout, 737 const MCFixup &Fixup, const MCFragment *DF, 738 MCValue &Target, uint64_t &Value) const; 739 740 /// Check whether a fixup can be satisfied, or whether it needs to be relaxed 741 /// (increased in size, in order to hold its value correctly). 742 bool fixupNeedsRelaxation(const MCFixup &Fixup, const MCInstFragment *DF, 743 const MCAsmLayout &Layout) const; 744 745 /// Check whether the given fragment needs relaxation. 746 bool fragmentNeedsRelaxation(const MCInstFragment *IF, 747 const MCAsmLayout &Layout) const; 748 749 /// layoutOnce - Perform one layout iteration and return true if any offsets 750 /// were adjusted. 751 bool layoutOnce(MCAsmLayout &Layout); 752 753 bool layoutSectionOnce(MCAsmLayout &Layout, MCSectionData &SD); 754 755 bool relaxInstruction(MCAsmLayout &Layout, MCInstFragment &IF); 756 757 bool relaxLEB(MCAsmLayout &Layout, MCLEBFragment &IF); 758 759 bool relaxDwarfLineAddr(MCAsmLayout &Layout, MCDwarfLineAddrFragment &DF); 760 bool relaxDwarfCallFrameFragment(MCAsmLayout &Layout, 761 MCDwarfCallFrameFragment &DF); 762 763 /// finishLayout - Finalize a layout, including fragment lowering. 764 void finishLayout(MCAsmLayout &Layout); 765 766 uint64_t handleFixup(const MCAsmLayout &Layout, 767 MCFragment &F, const MCFixup &Fixup); 768 769 public: 770 /// Compute the effective fragment size assuming it is laid out at the given 771 /// \arg SectionAddress and \arg FragmentOffset. 772 uint64_t computeFragmentSize(const MCAsmLayout &Layout, 773 const MCFragment &F) const; 774 775 /// Find the symbol which defines the atom containing the given symbol, or 776 /// null if there is no such symbol. 777 const MCSymbolData *getAtom(const MCSymbolData *Symbol) const; 778 779 /// Check whether a particular symbol is visible to the linker and is required 780 /// in the symbol table, or whether it can be discarded by the assembler. This 781 /// also effects whether the assembler treats the label as potentially 782 /// defining a separate atom. 783 bool isSymbolLinkerVisible(const MCSymbol &SD) const; 784 785 /// Emit the section contents using the given object writer. 786 void writeSectionData(const MCSectionData *Section, 787 const MCAsmLayout &Layout) const; 788 789 /// Check whether a given symbol has been flagged with .thumb_func. 790 bool isThumbFunc(const MCSymbol *Func) const { 791 return ThumbFuncs.count(Func); 792 } 793 794 /// Flag a function symbol as the target of a .thumb_func directive. 795 void setIsThumbFunc(const MCSymbol *Func) { ThumbFuncs.insert(Func); } 796 797 public: 798 /// Construct a new assembler instance. 799 /// 800 /// \arg OS - The stream to output to. 801 // 802 // FIXME: How are we going to parameterize this? Two obvious options are stay 803 // concrete and require clients to pass in a target like object. The other 804 // option is to make this abstract, and have targets provide concrete 805 // implementations as we do with AsmParser. 806 MCAssembler(MCContext &Context_, MCAsmBackend &Backend_, 807 MCCodeEmitter &Emitter_, MCObjectWriter &Writer_, 808 raw_ostream &OS); 809 ~MCAssembler(); 810 811 MCContext &getContext() const { return Context; } 812 813 MCAsmBackend &getBackend() const { return Backend; } 814 815 MCCodeEmitter &getEmitter() const { return Emitter; } 816 817 MCObjectWriter &getWriter() const { return *Writer; } 818 819 void setWriter(MCObjectWriter &ObjectWriter); 820 821 /// Finish - Do final processing and write the object to the output stream. 822 /// \arg Writer is used for custom object writer (as the MCJIT does), 823 /// if not specified it is automatically created from backend. 824 void Finish(); 825 826 // FIXME: This does not belong here. 827 bool getSubsectionsViaSymbols() const { 828 return SubsectionsViaSymbols; 829 } 830 void setSubsectionsViaSymbols(bool Value) { 831 SubsectionsViaSymbols = Value; 832 } 833 834 bool getRelaxAll() const { return RelaxAll; } 835 void setRelaxAll(bool Value) { RelaxAll = Value; } 836 837 bool getNoExecStack() const { return NoExecStack; } 838 void setNoExecStack(bool Value) { NoExecStack = Value; } 839 840 /// @name Section List Access 841 /// @{ 842 843 const SectionDataListType &getSectionList() const { return Sections; } 844 SectionDataListType &getSectionList() { return Sections; } 845 846 iterator begin() { return Sections.begin(); } 847 const_iterator begin() const { return Sections.begin(); } 848 849 iterator end() { return Sections.end(); } 850 const_iterator end() const { return Sections.end(); } 851 852 size_t size() const { return Sections.size(); } 853 854 /// @} 855 /// @name Symbol List Access 856 /// @{ 857 858 const SymbolDataListType &getSymbolList() const { return Symbols; } 859 SymbolDataListType &getSymbolList() { return Symbols; } 860 861 symbol_iterator symbol_begin() { return Symbols.begin(); } 862 const_symbol_iterator symbol_begin() const { return Symbols.begin(); } 863 864 symbol_iterator symbol_end() { return Symbols.end(); } 865 const_symbol_iterator symbol_end() const { return Symbols.end(); } 866 867 size_t symbol_size() const { return Symbols.size(); } 868 869 /// @} 870 /// @name Indirect Symbol List Access 871 /// @{ 872 873 // FIXME: This is a total hack, this should not be here. Once things are 874 // factored so that the streamer has direct access to the .o writer, it can 875 // disappear. 876 std::vector<IndirectSymbolData> &getIndirectSymbols() { 877 return IndirectSymbols; 878 } 879 880 indirect_symbol_iterator indirect_symbol_begin() { 881 return IndirectSymbols.begin(); 882 } 883 const_indirect_symbol_iterator indirect_symbol_begin() const { 884 return IndirectSymbols.begin(); 885 } 886 887 indirect_symbol_iterator indirect_symbol_end() { 888 return IndirectSymbols.end(); 889 } 890 const_indirect_symbol_iterator indirect_symbol_end() const { 891 return IndirectSymbols.end(); 892 } 893 894 size_t indirect_symbol_size() const { return IndirectSymbols.size(); } 895 896 /// @} 897 /// @name Backend Data Access 898 /// @{ 899 900 MCSectionData &getSectionData(const MCSection &Section) const { 901 MCSectionData *Entry = SectionMap.lookup(&Section); 902 assert(Entry && "Missing section data!"); 903 return *Entry; 904 } 905 906 MCSectionData &getOrCreateSectionData(const MCSection &Section, 907 bool *Created = 0) { 908 MCSectionData *&Entry = SectionMap[&Section]; 909 910 if (Created) *Created = !Entry; 911 if (!Entry) 912 Entry = new MCSectionData(Section, this); 913 914 return *Entry; 915 } 916 917 MCSymbolData &getSymbolData(const MCSymbol &Symbol) const { 918 MCSymbolData *Entry = SymbolMap.lookup(&Symbol); 919 assert(Entry && "Missing symbol data!"); 920 return *Entry; 921 } 922 923 MCSymbolData &getOrCreateSymbolData(const MCSymbol &Symbol, 924 bool *Created = 0) { 925 MCSymbolData *&Entry = SymbolMap[&Symbol]; 926 927 if (Created) *Created = !Entry; 928 if (!Entry) 929 Entry = new MCSymbolData(Symbol, 0, 0, this); 930 931 return *Entry; 932 } 933 934 /// @} 935 936 void dump(); 937 }; 938 939 } // end namespace llvm 940 941 #endif 942