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