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