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 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(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(MCInst Value)202 void setInst(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 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. isThumbFunc(const MCSymbol * 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. setIsThumbFunc(const MCSymbol * Func)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 getContext()811 MCContext &getContext() const { return Context; } 812 getBackend()813 MCAsmBackend &getBackend() const { return Backend; } 814 getEmitter()815 MCCodeEmitter &getEmitter() const { return Emitter; } 816 getWriter()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. getSubsectionsViaSymbols()827 bool getSubsectionsViaSymbols() const { 828 return SubsectionsViaSymbols; 829 } setSubsectionsViaSymbols(bool Value)830 void setSubsectionsViaSymbols(bool Value) { 831 SubsectionsViaSymbols = Value; 832 } 833 getRelaxAll()834 bool getRelaxAll() const { return RelaxAll; } setRelaxAll(bool Value)835 void setRelaxAll(bool Value) { RelaxAll = Value; } 836 getNoExecStack()837 bool getNoExecStack() const { return NoExecStack; } setNoExecStack(bool Value)838 void setNoExecStack(bool Value) { NoExecStack = Value; } 839 840 /// @name Section List Access 841 /// @{ 842 getSectionList()843 const SectionDataListType &getSectionList() const { return Sections; } getSectionList()844 SectionDataListType &getSectionList() { return Sections; } 845 begin()846 iterator begin() { return Sections.begin(); } begin()847 const_iterator begin() const { return Sections.begin(); } 848 end()849 iterator end() { return Sections.end(); } end()850 const_iterator end() const { return Sections.end(); } 851 size()852 size_t size() const { return Sections.size(); } 853 854 /// @} 855 /// @name Symbol List Access 856 /// @{ 857 getSymbolList()858 const SymbolDataListType &getSymbolList() const { return Symbols; } getSymbolList()859 SymbolDataListType &getSymbolList() { return Symbols; } 860 symbol_begin()861 symbol_iterator symbol_begin() { return Symbols.begin(); } symbol_begin()862 const_symbol_iterator symbol_begin() const { return Symbols.begin(); } 863 symbol_end()864 symbol_iterator symbol_end() { return Symbols.end(); } symbol_end()865 const_symbol_iterator symbol_end() const { return Symbols.end(); } 866 symbol_size()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. getIndirectSymbols()876 std::vector<IndirectSymbolData> &getIndirectSymbols() { 877 return IndirectSymbols; 878 } 879 indirect_symbol_begin()880 indirect_symbol_iterator indirect_symbol_begin() { 881 return IndirectSymbols.begin(); 882 } indirect_symbol_begin()883 const_indirect_symbol_iterator indirect_symbol_begin() const { 884 return IndirectSymbols.begin(); 885 } 886 indirect_symbol_end()887 indirect_symbol_iterator indirect_symbol_end() { 888 return IndirectSymbols.end(); 889 } indirect_symbol_end()890 const_indirect_symbol_iterator indirect_symbol_end() const { 891 return IndirectSymbols.end(); 892 } 893 indirect_symbol_size()894 size_t indirect_symbol_size() const { return IndirectSymbols.size(); } 895 896 /// @} 897 /// @name Backend Data Access 898 /// @{ 899 getSectionData(const MCSection & Section)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 getSymbolData(const MCSymbol & Symbol)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