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&) 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_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 getKind()99 FragmentType getKind() const { return Kind; } 100 getParent()101 MCSectionData *getParent() const { return Parent; } setParent(MCSectionData * Value)102 void setParent(MCSectionData *Value) { Parent = Value; } 103 getAtom()104 MCSymbolData *getAtom() const { return Atom; } setAtom(MCSymbolData * Value)105 void setAtom(MCSymbolData *Value) { Atom = Value; } 106 getLayoutOrder()107 unsigned getLayoutOrder() const { return LayoutOrder; } setLayoutOrder(unsigned Value)108 void setLayoutOrder(unsigned Value) { LayoutOrder = Value; } 109 classof(const MCFragment * O)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: MCFragment(FT_Data,SD)127 MCDataFragment(MCSectionData *SD = 0) : MCFragment(FT_Data, SD) {} 128 129 /// @name Accessors 130 /// @{ 131 getContents()132 SmallString<32> &getContents() { return Contents; } getContents()133 const SmallString<32> &getContents() const { return Contents; } 134 135 /// @} 136 /// @name Fixup Access 137 /// @{ 138 addFixup(MCFixup Fixup)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 getFixups()146 std::vector<MCFixup> &getFixups() { return Fixups; } getFixups()147 const std::vector<MCFixup> &getFixups() const { return Fixups; } 148 fixup_begin()149 fixup_iterator fixup_begin() { return Fixups.begin(); } fixup_begin()150 const_fixup_iterator fixup_begin() const { return Fixups.begin(); } 151 fixup_end()152 fixup_iterator fixup_end() {return Fixups.end();} fixup_end()153 const_fixup_iterator fixup_end() const {return Fixups.end();} 154 fixup_size()155 size_t fixup_size() const { return Fixups.size(); } 156 157 /// @} 158 classof(const MCFragment * F)159 static bool classof(const MCFragment *F) { 160 return F->getKind() == MCFragment::FT_Data; 161 } classof(const MCDataFragment *)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(const MCInst &_Inst, MCSectionData *SD = 0) MCFragment(FT_Inst,SD)188 : MCFragment(FT_Inst, SD), Inst(_Inst) { 189 } 190 191 /// @name Accessors 192 /// @{ 193 getCode()194 SmallVectorImpl<char> &getCode() { return Code; } getCode()195 const SmallVectorImpl<char> &getCode() const { return Code; } 196 getInstSize()197 unsigned getInstSize() const { return Code.size(); } 198 getInst()199 MCInst &getInst() { return Inst; } getInst()200 const MCInst &getInst() const { return Inst; } 201 setInst(const MCInst & Value)202 void setInst(const MCInst& Value) { Inst = Value; } 203 204 /// @} 205 /// @name Fixup Access 206 /// @{ 207 getFixups()208 SmallVectorImpl<MCFixup> &getFixups() { return Fixups; } getFixups()209 const SmallVectorImpl<MCFixup> &getFixups() const { return Fixups; } 210 fixup_begin()211 fixup_iterator fixup_begin() { return Fixups.begin(); } fixup_begin()212 const_fixup_iterator fixup_begin() const { return Fixups.begin(); } 213 fixup_end()214 fixup_iterator fixup_end() {return Fixups.end();} fixup_end()215 const_fixup_iterator fixup_end() const {return Fixups.end();} 216 fixup_size()217 size_t fixup_size() const { return Fixups.size(); } 218 219 /// @} 220 classof(const MCFragment * F)221 static bool classof(const MCFragment *F) { 222 return F->getKind() == MCFragment::FT_Inst; 223 } classof(const MCInstFragment *)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) MCFragment(FT_Align,SD)251 : MCFragment(FT_Align, SD), Alignment(_Alignment), 252 Value(_Value),ValueSize(_ValueSize), 253 MaxBytesToEmit(_MaxBytesToEmit), EmitNops(false) {} 254 255 /// @name Accessors 256 /// @{ 257 getAlignment()258 unsigned getAlignment() const { return Alignment; } 259 getValue()260 int64_t getValue() const { return Value; } 261 getValueSize()262 unsigned getValueSize() const { return ValueSize; } 263 getMaxBytesToEmit()264 unsigned getMaxBytesToEmit() const { return MaxBytesToEmit; } 265 hasEmitNops()266 bool hasEmitNops() const { return EmitNops; } setEmitNops(bool Value)267 void setEmitNops(bool Value) { EmitNops = Value; } 268 269 /// @} 270 classof(const MCFragment * F)271 static bool classof(const MCFragment *F) { 272 return F->getKind() == MCFragment::FT_Align; 273 } classof(const MCAlignFragment *)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) MCFragment(FT_Fill,SD)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 getValue()302 int64_t getValue() const { return Value; } 303 getValueSize()304 unsigned getValueSize() const { return ValueSize; } 305 getSize()306 uint64_t getSize() const { return Size; } 307 308 /// @} 309 classof(const MCFragment * F)310 static bool classof(const MCFragment *F) { 311 return F->getKind() == MCFragment::FT_Fill; 312 } classof(const MCFillFragment *)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) MCFragment(FT_Org,SD)327 : MCFragment(FT_Org, SD), 328 Offset(&_Offset), Value(_Value) {} 329 330 /// @name Accessors 331 /// @{ 332 getOffset()333 const MCExpr &getOffset() const { return *Offset; } 334 getValue()335 uint8_t getValue() const { return Value; } 336 337 /// @} 338 classof(const MCFragment * F)339 static bool classof(const MCFragment *F) { 340 return F->getKind() == MCFragment::FT_Org; 341 } classof(const MCOrgFragment *)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: MCLEBFragment(const MCExpr & Value_,bool IsSigned_,MCSectionData * SD)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 getValue()363 const MCExpr &getValue() const { return *Value; } 364 isSigned()365 bool isSigned() const { return IsSigned; } 366 getContents()367 SmallString<8> &getContents() { return Contents; } getContents()368 const SmallString<8> &getContents() const { return Contents; } 369 370 /// @} 371 classof(const MCFragment * F)372 static bool classof(const MCFragment *F) { 373 return F->getKind() == MCFragment::FT_LEB; 374 } classof(const MCLEBFragment *)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: MCDwarfLineAddrFragment(int64_t _LineDelta,const MCExpr & _AddrDelta,MCSectionData * SD)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 getLineDelta()400 int64_t getLineDelta() const { return LineDelta; } 401 getAddrDelta()402 const MCExpr &getAddrDelta() const { return *AddrDelta; } 403 getContents()404 SmallString<8> &getContents() { return Contents; } getContents()405 const SmallString<8> &getContents() const { return Contents; } 406 407 /// @} 408 classof(const MCFragment * F)409 static bool classof(const MCFragment *F) { 410 return F->getKind() == MCFragment::FT_Dwarf; 411 } classof(const MCDwarfLineAddrFragment *)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: MCDwarfCallFrameFragment(const MCExpr & _AddrDelta,MCSectionData * SD)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 getAddrDelta()432 const MCExpr &getAddrDelta() const { return *AddrDelta; } 433 getContents()434 SmallString<8> &getContents() { return Contents; } getContents()435 const SmallString<8> &getContents() const { return Contents; } 436 437 /// @} 438 classof(const MCFragment * F)439 static bool classof(const MCFragment *F) { 440 return F->getKind() == MCFragment::FT_DwarfFrame; 441 } classof(const MCDwarfCallFrameFragment *)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 getSection()492 const MCSection &getSection() const { return *Section; } 493 getAlignment()494 unsigned getAlignment() const { return Alignment; } setAlignment(unsigned Value)495 void setAlignment(unsigned Value) { Alignment = Value; } 496 hasInstructions()497 bool hasInstructions() const { return HasInstructions; } setHasInstructions(bool Value)498 void setHasInstructions(bool Value) { HasInstructions = Value; } 499 getOrdinal()500 unsigned getOrdinal() const { return Ordinal; } setOrdinal(unsigned Value)501 void setOrdinal(unsigned Value) { Ordinal = Value; } 502 getLayoutOrder()503 unsigned getLayoutOrder() const { return LayoutOrder; } setLayoutOrder(unsigned Value)504 void setLayoutOrder(unsigned Value) { LayoutOrder = Value; } 505 506 /// @name Fragment Access 507 /// @{ 508 getFragmentList()509 const FragmentListType &getFragmentList() const { return Fragments; } getFragmentList()510 FragmentListType &getFragmentList() { return Fragments; } 511 begin()512 iterator begin() { return Fragments.begin(); } begin()513 const_iterator begin() const { return Fragments.begin(); } 514 end()515 iterator end() { return Fragments.end(); } end()516 const_iterator end() const { return Fragments.end(); } 517 rbegin()518 reverse_iterator rbegin() { return Fragments.rbegin(); } rbegin()519 const_reverse_iterator rbegin() const { return Fragments.rbegin(); } 520 rend()521 reverse_iterator rend() { return Fragments.rend(); } rend()522 const_reverse_iterator rend() const { return Fragments.rend(); } 523 size()524 size_t size() const { return Fragments.size(); } 525 empty()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 getSymbol()583 const MCSymbol &getSymbol() const { return *Symbol; } 584 getFragment()585 MCFragment *getFragment() const { return Fragment; } setFragment(MCFragment * Value)586 void setFragment(MCFragment *Value) { Fragment = Value; } 587 getOffset()588 uint64_t getOffset() const { return Offset; } setOffset(uint64_t Value)589 void setOffset(uint64_t Value) { Offset = Value; } 590 591 /// @} 592 /// @name Symbol Attributes 593 /// @{ 594 isExternal()595 bool isExternal() const { return IsExternal; } setExternal(bool Value)596 void setExternal(bool Value) { IsExternal = Value; } 597 isPrivateExtern()598 bool isPrivateExtern() const { return IsPrivateExtern; } setPrivateExtern(bool Value)599 void setPrivateExtern(bool Value) { IsPrivateExtern = Value; } 600 601 /// isCommon - Is this a 'common' symbol. isCommon()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. setCommon(uint64_t Size,unsigned Align)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. getCommonSize()614 uint64_t getCommonSize() const { 615 assert(isCommon() && "Not a 'common' symbol!"); 616 return CommonSize; 617 } 618 setSize(const MCExpr * SS)619 void setSize(const MCExpr *SS) { 620 SymbolSize = SS; 621 } 622 getSize()623 const MCExpr *getSize() const { 624 return SymbolSize; 625 } 626 627 628 /// getCommonAlignment - Return the alignment of a 'common' symbol. getCommonAlignment()629 unsigned getCommonAlignment() const { 630 assert(isCommon() && "Not a 'common' symbol!"); 631 return CommonAlign; 632 } 633 634 /// getFlags - Get the (implementation defined) symbol flags. getFlags()635 uint32_t getFlags() const { return Flags; } 636 637 /// setFlags - Set the (implementation defined) symbol flags. setFlags(uint32_t Value)638 void setFlags(uint32_t Value) { Flags = Value; } 639 640 /// modifyFlags - Modify the flags via a mask modifyFlags(uint32_t Value,uint32_t Mask)641 void modifyFlags(uint32_t Value, uint32_t Mask) { 642 Flags = (Flags & ~Mask) | Value; 643 } 644 645 /// getIndex - Get the (implementation defined) index. getIndex()646 uint64_t getIndex() const { return Index; } 647 648 /// setIndex - Set the (implementation defined) index. setIndex(uint64_t Value)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 // FIXME: Ditto this. Purely so the Streamer and the ObjectWriter can talk 663 // to one another. 664 struct DataRegionData { 665 // This enum should be kept in sync w/ the mach-o definition in 666 // llvm/Object/MachOFormat.h. 667 enum KindTy { Data = 1, JumpTable8, JumpTable16, JumpTable32 } Kind; 668 MCSymbol *Start; 669 MCSymbol *End; 670 }; 671 672 class MCAssembler { 673 friend class MCAsmLayout; 674 675 public: 676 typedef iplist<MCSectionData> SectionDataListType; 677 typedef iplist<MCSymbolData> SymbolDataListType; 678 679 typedef SectionDataListType::const_iterator const_iterator; 680 typedef SectionDataListType::iterator iterator; 681 682 typedef SymbolDataListType::const_iterator const_symbol_iterator; 683 typedef SymbolDataListType::iterator symbol_iterator; 684 685 typedef std::vector<IndirectSymbolData>::const_iterator 686 const_indirect_symbol_iterator; 687 typedef std::vector<IndirectSymbolData>::iterator indirect_symbol_iterator; 688 689 typedef std::vector<DataRegionData>::const_iterator 690 const_data_region_iterator; 691 typedef std::vector<DataRegionData>::iterator data_region_iterator; 692 693 private: 694 MCAssembler(const MCAssembler&); // DO NOT IMPLEMENT 695 void operator=(const MCAssembler&); // DO NOT IMPLEMENT 696 697 MCContext &Context; 698 699 MCAsmBackend &Backend; 700 701 MCCodeEmitter &Emitter; 702 703 MCObjectWriter *Writer; 704 705 raw_ostream &OS; 706 707 iplist<MCSectionData> Sections; 708 709 iplist<MCSymbolData> Symbols; 710 711 /// The map of sections to their associated assembler backend data. 712 // 713 // FIXME: Avoid this indirection? 714 DenseMap<const MCSection*, MCSectionData*> SectionMap; 715 716 /// The map of symbols to their associated assembler backend data. 717 // 718 // FIXME: Avoid this indirection? 719 DenseMap<const MCSymbol*, MCSymbolData*> SymbolMap; 720 721 std::vector<IndirectSymbolData> IndirectSymbols; 722 723 std::vector<DataRegionData> DataRegions; 724 /// The set of function symbols for which a .thumb_func directive has 725 /// been seen. 726 // 727 // FIXME: We really would like this in target specific code rather than 728 // here. Maybe when the relocation stuff moves to target specific, 729 // this can go with it? The streamer would need some target specific 730 // refactoring too. 731 SmallPtrSet<const MCSymbol*, 64> ThumbFuncs; 732 733 unsigned RelaxAll : 1; 734 unsigned NoExecStack : 1; 735 unsigned SubsectionsViaSymbols : 1; 736 737 private: 738 /// Evaluate a fixup to a relocatable expression and the value which should be 739 /// placed into the fixup. 740 /// 741 /// \param Layout The layout to use for evaluation. 742 /// \param Fixup The fixup to evaluate. 743 /// \param DF The fragment the fixup is inside. 744 /// \param Target [out] On return, the relocatable expression the fixup 745 /// evaluates to. 746 /// \param Value [out] On return, the value of the fixup as currently laid 747 /// out. 748 /// \return Whether the fixup value was fully resolved. This is true if the 749 /// \arg Value result is fixed, otherwise the value may change due to 750 /// relocation. 751 bool evaluateFixup(const MCAsmLayout &Layout, 752 const MCFixup &Fixup, const MCFragment *DF, 753 MCValue &Target, uint64_t &Value) const; 754 755 /// Check whether a fixup can be satisfied, or whether it needs to be relaxed 756 /// (increased in size, in order to hold its value correctly). 757 bool fixupNeedsRelaxation(const MCFixup &Fixup, const MCInstFragment *DF, 758 const MCAsmLayout &Layout) const; 759 760 /// Check whether the given fragment needs relaxation. 761 bool fragmentNeedsRelaxation(const MCInstFragment *IF, 762 const MCAsmLayout &Layout) const; 763 764 /// layoutOnce - Perform one layout iteration and return true if any offsets 765 /// were adjusted. 766 bool layoutOnce(MCAsmLayout &Layout); 767 768 bool layoutSectionOnce(MCAsmLayout &Layout, MCSectionData &SD); 769 770 bool relaxInstruction(MCAsmLayout &Layout, MCInstFragment &IF); 771 772 bool relaxLEB(MCAsmLayout &Layout, MCLEBFragment &IF); 773 774 bool relaxDwarfLineAddr(MCAsmLayout &Layout, MCDwarfLineAddrFragment &DF); 775 bool relaxDwarfCallFrameFragment(MCAsmLayout &Layout, 776 MCDwarfCallFrameFragment &DF); 777 778 /// finishLayout - Finalize a layout, including fragment lowering. 779 void finishLayout(MCAsmLayout &Layout); 780 781 uint64_t handleFixup(const MCAsmLayout &Layout, 782 MCFragment &F, const MCFixup &Fixup); 783 784 public: 785 /// Compute the effective fragment size assuming it is laid out at the given 786 /// \arg SectionAddress and \arg FragmentOffset. 787 uint64_t computeFragmentSize(const MCAsmLayout &Layout, 788 const MCFragment &F) const; 789 790 /// Find the symbol which defines the atom containing the given symbol, or 791 /// null if there is no such symbol. 792 const MCSymbolData *getAtom(const MCSymbolData *Symbol) const; 793 794 /// Check whether a particular symbol is visible to the linker and is required 795 /// in the symbol table, or whether it can be discarded by the assembler. This 796 /// also effects whether the assembler treats the label as potentially 797 /// defining a separate atom. 798 bool isSymbolLinkerVisible(const MCSymbol &SD) const; 799 800 /// Emit the section contents using the given object writer. 801 void writeSectionData(const MCSectionData *Section, 802 const MCAsmLayout &Layout) const; 803 804 /// Check whether a given symbol has been flagged with .thumb_func. isThumbFunc(const MCSymbol * Func)805 bool isThumbFunc(const MCSymbol *Func) const { 806 return ThumbFuncs.count(Func); 807 } 808 809 /// Flag a function symbol as the target of a .thumb_func directive. setIsThumbFunc(const MCSymbol * Func)810 void setIsThumbFunc(const MCSymbol *Func) { ThumbFuncs.insert(Func); } 811 812 public: 813 /// Construct a new assembler instance. 814 /// 815 /// \arg OS - The stream to output to. 816 // 817 // FIXME: How are we going to parameterize this? Two obvious options are stay 818 // concrete and require clients to pass in a target like object. The other 819 // option is to make this abstract, and have targets provide concrete 820 // implementations as we do with AsmParser. 821 MCAssembler(MCContext &Context_, MCAsmBackend &Backend_, 822 MCCodeEmitter &Emitter_, MCObjectWriter &Writer_, 823 raw_ostream &OS); 824 ~MCAssembler(); 825 getContext()826 MCContext &getContext() const { return Context; } 827 getBackend()828 MCAsmBackend &getBackend() const { return Backend; } 829 getEmitter()830 MCCodeEmitter &getEmitter() const { return Emitter; } 831 getWriter()832 MCObjectWriter &getWriter() const { return *Writer; } 833 834 void setWriter(MCObjectWriter &ObjectWriter); 835 836 /// Finish - Do final processing and write the object to the output stream. 837 /// \arg Writer is used for custom object writer (as the MCJIT does), 838 /// if not specified it is automatically created from backend. 839 void Finish(); 840 841 // FIXME: This does not belong here. getSubsectionsViaSymbols()842 bool getSubsectionsViaSymbols() const { 843 return SubsectionsViaSymbols; 844 } setSubsectionsViaSymbols(bool Value)845 void setSubsectionsViaSymbols(bool Value) { 846 SubsectionsViaSymbols = Value; 847 } 848 getRelaxAll()849 bool getRelaxAll() const { return RelaxAll; } setRelaxAll(bool Value)850 void setRelaxAll(bool Value) { RelaxAll = Value; } 851 getNoExecStack()852 bool getNoExecStack() const { return NoExecStack; } setNoExecStack(bool Value)853 void setNoExecStack(bool Value) { NoExecStack = Value; } 854 855 /// @name Section List Access 856 /// @{ 857 getSectionList()858 const SectionDataListType &getSectionList() const { return Sections; } getSectionList()859 SectionDataListType &getSectionList() { return Sections; } 860 begin()861 iterator begin() { return Sections.begin(); } begin()862 const_iterator begin() const { return Sections.begin(); } 863 end()864 iterator end() { return Sections.end(); } end()865 const_iterator end() const { return Sections.end(); } 866 size()867 size_t size() const { return Sections.size(); } 868 869 /// @} 870 /// @name Symbol List Access 871 /// @{ 872 getSymbolList()873 const SymbolDataListType &getSymbolList() const { return Symbols; } getSymbolList()874 SymbolDataListType &getSymbolList() { return Symbols; } 875 symbol_begin()876 symbol_iterator symbol_begin() { return Symbols.begin(); } symbol_begin()877 const_symbol_iterator symbol_begin() const { return Symbols.begin(); } 878 symbol_end()879 symbol_iterator symbol_end() { return Symbols.end(); } symbol_end()880 const_symbol_iterator symbol_end() const { return Symbols.end(); } 881 symbol_size()882 size_t symbol_size() const { return Symbols.size(); } 883 884 /// @} 885 /// @name Indirect Symbol List Access 886 /// @{ 887 888 // FIXME: This is a total hack, this should not be here. Once things are 889 // factored so that the streamer has direct access to the .o writer, it can 890 // disappear. getIndirectSymbols()891 std::vector<IndirectSymbolData> &getIndirectSymbols() { 892 return IndirectSymbols; 893 } 894 indirect_symbol_begin()895 indirect_symbol_iterator indirect_symbol_begin() { 896 return IndirectSymbols.begin(); 897 } indirect_symbol_begin()898 const_indirect_symbol_iterator indirect_symbol_begin() const { 899 return IndirectSymbols.begin(); 900 } 901 indirect_symbol_end()902 indirect_symbol_iterator indirect_symbol_end() { 903 return IndirectSymbols.end(); 904 } indirect_symbol_end()905 const_indirect_symbol_iterator indirect_symbol_end() const { 906 return IndirectSymbols.end(); 907 } 908 indirect_symbol_size()909 size_t indirect_symbol_size() const { return IndirectSymbols.size(); } 910 911 /// @} 912 /// @name Data Region List Access 913 /// @{ 914 915 // FIXME: This is a total hack, this should not be here. Once things are 916 // factored so that the streamer has direct access to the .o writer, it can 917 // disappear. getDataRegions()918 std::vector<DataRegionData> &getDataRegions() { 919 return DataRegions; 920 } 921 data_region_begin()922 data_region_iterator data_region_begin() { 923 return DataRegions.begin(); 924 } data_region_begin()925 const_data_region_iterator data_region_begin() const { 926 return DataRegions.begin(); 927 } 928 data_region_end()929 data_region_iterator data_region_end() { 930 return DataRegions.end(); 931 } data_region_end()932 const_data_region_iterator data_region_end() const { 933 return DataRegions.end(); 934 } 935 data_region_size()936 size_t data_region_size() const { return DataRegions.size(); } 937 938 /// @} 939 /// @name Backend Data Access 940 /// @{ 941 getSectionData(const MCSection & Section)942 MCSectionData &getSectionData(const MCSection &Section) const { 943 MCSectionData *Entry = SectionMap.lookup(&Section); 944 assert(Entry && "Missing section data!"); 945 return *Entry; 946 } 947 948 MCSectionData &getOrCreateSectionData(const MCSection &Section, 949 bool *Created = 0) { 950 MCSectionData *&Entry = SectionMap[&Section]; 951 952 if (Created) *Created = !Entry; 953 if (!Entry) 954 Entry = new MCSectionData(Section, this); 955 956 return *Entry; 957 } 958 getSymbolData(const MCSymbol & Symbol)959 MCSymbolData &getSymbolData(const MCSymbol &Symbol) const { 960 MCSymbolData *Entry = SymbolMap.lookup(&Symbol); 961 assert(Entry && "Missing symbol data!"); 962 return *Entry; 963 } 964 965 MCSymbolData &getOrCreateSymbolData(const MCSymbol &Symbol, 966 bool *Created = 0) { 967 MCSymbolData *&Entry = SymbolMap[&Symbol]; 968 969 if (Created) *Created = !Entry; 970 if (!Entry) 971 Entry = new MCSymbolData(Symbol, 0, 0, this); 972 973 return *Entry; 974 } 975 976 /// @} 977 978 void dump(); 979 }; 980 981 } // end namespace llvm 982 983 #endif 984