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