MCAssembler.h revision 53b2338a1d061ad15a858ff0d641431f4d4ac101
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/SmallString.h" 15#include "llvm/ADT/ilist.h" 16#include "llvm/ADT/ilist_node.h" 17#include "llvm/Support/Casting.h" 18#include "llvm/MC/MCFixup.h" 19#include "llvm/System/DataTypes.h" 20#include <vector> // FIXME: Shouldn't be needed. 21 22namespace llvm { 23class raw_ostream; 24class MCAsmLayout; 25class MCAssembler; 26class MCContext; 27class MCExpr; 28class MCFragment; 29class MCObjectWriter; 30class MCSection; 31class MCSectionData; 32class MCSymbol; 33class MCValue; 34class TargetAsmBackend; 35 36/// MCAsmFixup - Represent a fixed size region of bytes inside some fragment 37/// which needs to be rewritten. This region will either be rewritten by the 38/// assembler or cause a relocation entry to be generated. 39struct MCAsmFixup { 40 /// Offset - The offset inside the fragment which needs to be rewritten. 41 uint64_t Offset; 42 43 /// Value - The expression to eventually write into the fragment. 44 const MCExpr *Value; 45 46 /// Kind - The fixup kind. 47 MCFixupKind Kind; 48 49public: 50 MCAsmFixup(uint64_t _Offset, const MCExpr &_Value, MCFixupKind _Kind) 51 : Offset(_Offset), Value(&_Value), Kind(_Kind) {} 52}; 53 54class MCFragment : public ilist_node<MCFragment> { 55 MCFragment(const MCFragment&); // DO NOT IMPLEMENT 56 void operator=(const MCFragment&); // DO NOT IMPLEMENT 57 58public: 59 enum FragmentType { 60 FT_Data, 61 FT_Align, 62 FT_Fill, 63 FT_Org, 64 FT_ZeroFill 65 }; 66 67private: 68 FragmentType Kind; 69 70 /// Parent - The data for the section this fragment is in. 71 MCSectionData *Parent; 72 73 /// @name Assembler Backend Data 74 /// @{ 75 // 76 // FIXME: This could all be kept private to the assembler implementation. 77 78 /// Offset - The offset of this fragment in its section. This is ~0 until 79 /// initialized. 80 uint64_t Offset; 81 82 /// FileSize - The file size of this section. This is ~0 until initialized. 83 uint64_t FileSize; 84 85 /// @} 86 87protected: 88 MCFragment(FragmentType _Kind, MCSectionData *_Parent = 0); 89 90public: 91 // Only for sentinel. 92 MCFragment(); 93 virtual ~MCFragment(); 94 95 FragmentType getKind() const { return Kind; } 96 97 MCSectionData *getParent() const { return Parent; } 98 void setParent(MCSectionData *Value) { Parent = Value; } 99 100 // FIXME: This should be abstract, fix sentinel. 101 virtual uint64_t getMaxFileSize() const { 102 assert(0 && "Invalid getMaxFileSize call!"); 103 return 0; 104 } 105 106 /// @name Assembler Backend Support 107 /// @{ 108 // 109 // FIXME: This could all be kept private to the assembler implementation. 110 111 uint64_t getAddress() const; 112 113 uint64_t getFileSize() const { 114 assert(FileSize != ~UINT64_C(0) && "File size not set!"); 115 return FileSize; 116 } 117 void setFileSize(uint64_t Value) { 118 assert(Value <= getMaxFileSize() && "Invalid file size!"); 119 FileSize = Value; 120 } 121 122 uint64_t getOffset() const { 123 assert(Offset != ~UINT64_C(0) && "File offset not set!"); 124 return Offset; 125 } 126 void setOffset(uint64_t Value) { Offset = Value; } 127 128 /// @} 129 130 static bool classof(const MCFragment *O) { return true; } 131 132 virtual void dump(); 133}; 134 135class MCDataFragment : public MCFragment { 136 SmallString<32> Contents; 137 138 /// Fixups - The list of fixups in this fragment. 139 std::vector<MCAsmFixup> Fixups; 140 141public: 142 typedef std::vector<MCAsmFixup>::const_iterator const_fixup_iterator; 143 typedef std::vector<MCAsmFixup>::iterator fixup_iterator; 144 145public: 146 MCDataFragment(MCSectionData *SD = 0) : MCFragment(FT_Data, SD) {} 147 148 /// @name Accessors 149 /// @{ 150 151 uint64_t getMaxFileSize() const { 152 return Contents.size(); 153 } 154 155 SmallString<32> &getContents() { return Contents; } 156 const SmallString<32> &getContents() const { return Contents; } 157 158 /// @} 159 160 /// @name Fixup Access 161 /// @{ 162 163 void addFixup(MCAsmFixup Fixup) { 164 // Enforce invariant that fixups are in offset order. 165 assert((Fixups.empty() || Fixup.Offset > Fixups.back().Offset) && 166 "Fixups must be added in order!"); 167 Fixups.push_back(Fixup); 168 } 169 170 std::vector<MCAsmFixup> &getFixups() { return Fixups; } 171 const std::vector<MCAsmFixup> &getFixups() const { return Fixups; } 172 173 fixup_iterator fixup_begin() { return Fixups.begin(); } 174 const_fixup_iterator fixup_begin() const { return Fixups.begin(); } 175 176 fixup_iterator fixup_end() {return Fixups.end();} 177 const_fixup_iterator fixup_end() const {return Fixups.end();} 178 179 size_t fixup_size() const { return Fixups.size(); } 180 181 /// @} 182 183 static bool classof(const MCFragment *F) { 184 return F->getKind() == MCFragment::FT_Data; 185 } 186 static bool classof(const MCDataFragment *) { return true; } 187 188 virtual void dump(); 189}; 190 191class MCAlignFragment : public MCFragment { 192 /// Alignment - The alignment to ensure, in bytes. 193 unsigned Alignment; 194 195 /// Value - Value to use for filling padding bytes. 196 int64_t Value; 197 198 /// ValueSize - The size of the integer (in bytes) of \arg Value. 199 unsigned ValueSize; 200 201 /// MaxBytesToEmit - The maximum number of bytes to emit; if the alignment 202 /// cannot be satisfied in this width then this fragment is ignored. 203 unsigned MaxBytesToEmit; 204 205 /// EmitNops - true when aligning code and optimal nops to be used for 206 /// filling. 207 bool EmitNops; 208 209public: 210 MCAlignFragment(unsigned _Alignment, int64_t _Value, unsigned _ValueSize, 211 unsigned _MaxBytesToEmit, bool _EmitNops, 212 MCSectionData *SD = 0) 213 : MCFragment(FT_Align, SD), Alignment(_Alignment), 214 Value(_Value),ValueSize(_ValueSize), 215 MaxBytesToEmit(_MaxBytesToEmit), EmitNops(_EmitNops) {} 216 217 /// @name Accessors 218 /// @{ 219 220 uint64_t getMaxFileSize() const { 221 return std::max(Alignment - 1, MaxBytesToEmit); 222 } 223 224 unsigned getAlignment() const { return Alignment; } 225 226 int64_t getValue() const { return Value; } 227 228 unsigned getValueSize() const { return ValueSize; } 229 230 unsigned getMaxBytesToEmit() const { return MaxBytesToEmit; } 231 232 unsigned getEmitNops() const { return EmitNops; } 233 234 /// @} 235 236 static bool classof(const MCFragment *F) { 237 return F->getKind() == MCFragment::FT_Align; 238 } 239 static bool classof(const MCAlignFragment *) { return true; } 240 241 virtual void dump(); 242}; 243 244class MCFillFragment : public MCFragment { 245 /// Value - Value to use for filling bytes. 246 int64_t Value; 247 248 /// ValueSize - The size (in bytes) of \arg Value to use when filling. 249 unsigned ValueSize; 250 251 /// Count - The number of copies of \arg Value to insert. 252 uint64_t Count; 253 254public: 255 MCFillFragment(int64_t _Value, unsigned _ValueSize, uint64_t _Count, 256 MCSectionData *SD = 0) 257 : MCFragment(FT_Fill, SD), 258 Value(_Value), ValueSize(_ValueSize), Count(_Count) {} 259 260 /// @name Accessors 261 /// @{ 262 263 uint64_t getMaxFileSize() const { 264 return ValueSize * Count; 265 } 266 267 int64_t getValue() const { return Value; } 268 269 unsigned getValueSize() const { return ValueSize; } 270 271 uint64_t getCount() const { return Count; } 272 273 /// @} 274 275 static bool classof(const MCFragment *F) { 276 return F->getKind() == MCFragment::FT_Fill; 277 } 278 static bool classof(const MCFillFragment *) { return true; } 279 280 virtual void dump(); 281}; 282 283class MCOrgFragment : public MCFragment { 284 /// Offset - The offset this fragment should start at. 285 const MCExpr *Offset; 286 287 /// Value - Value to use for filling bytes. 288 int8_t Value; 289 290public: 291 MCOrgFragment(const MCExpr &_Offset, int8_t _Value, MCSectionData *SD = 0) 292 : MCFragment(FT_Org, SD), 293 Offset(&_Offset), Value(_Value) {} 294 295 /// @name Accessors 296 /// @{ 297 298 uint64_t getMaxFileSize() const { 299 // FIXME: This doesn't make much sense. 300 return ~UINT64_C(0); 301 } 302 303 const MCExpr &getOffset() const { return *Offset; } 304 305 uint8_t getValue() const { return Value; } 306 307 /// @} 308 309 static bool classof(const MCFragment *F) { 310 return F->getKind() == MCFragment::FT_Org; 311 } 312 static bool classof(const MCOrgFragment *) { return true; } 313 314 virtual void dump(); 315}; 316 317/// MCZeroFillFragment - Represent data which has a fixed size and alignment, 318/// but requires no physical space in the object file. 319class MCZeroFillFragment : public MCFragment { 320 /// Size - The size of this fragment. 321 uint64_t Size; 322 323 /// Alignment - The alignment for this fragment. 324 unsigned Alignment; 325 326public: 327 MCZeroFillFragment(uint64_t _Size, unsigned _Alignment, MCSectionData *SD = 0) 328 : MCFragment(FT_ZeroFill, SD), 329 Size(_Size), Alignment(_Alignment) {} 330 331 /// @name Accessors 332 /// @{ 333 334 uint64_t getMaxFileSize() const { 335 // FIXME: This also doesn't make much sense, this method is misnamed. 336 return ~UINT64_C(0); 337 } 338 339 uint64_t getSize() const { return Size; } 340 341 unsigned getAlignment() const { return Alignment; } 342 343 /// @} 344 345 static bool classof(const MCFragment *F) { 346 return F->getKind() == MCFragment::FT_ZeroFill; 347 } 348 static bool classof(const MCZeroFillFragment *) { return true; } 349 350 virtual void dump(); 351}; 352 353// FIXME: Should this be a separate class, or just merged into MCSection? Since 354// we anticipate the fast path being through an MCAssembler, the only reason to 355// keep it out is for API abstraction. 356class MCSectionData : public ilist_node<MCSectionData> { 357 MCSectionData(const MCSectionData&); // DO NOT IMPLEMENT 358 void operator=(const MCSectionData&); // DO NOT IMPLEMENT 359 360public: 361 typedef iplist<MCFragment> FragmentListType; 362 363 typedef FragmentListType::const_iterator const_iterator; 364 typedef FragmentListType::iterator iterator; 365 366 typedef FragmentListType::const_reverse_iterator const_reverse_iterator; 367 typedef FragmentListType::reverse_iterator reverse_iterator; 368 369private: 370 iplist<MCFragment> Fragments; 371 const MCSection *Section; 372 373 /// Alignment - The maximum alignment seen in this section. 374 unsigned Alignment; 375 376 /// @name Assembler Backend Data 377 /// @{ 378 // 379 // FIXME: This could all be kept private to the assembler implementation. 380 381 /// Address - The computed address of this section. This is ~0 until 382 /// initialized. 383 uint64_t Address; 384 385 /// Size - The content size of this section. This is ~0 until initialized. 386 uint64_t Size; 387 388 /// FileSize - The size of this section in the object file. This is ~0 until 389 /// initialized. 390 uint64_t FileSize; 391 392 /// HasInstructions - Whether this section has had instructions emitted into 393 /// it. 394 unsigned HasInstructions : 1; 395 396 /// @} 397 398public: 399 // Only for use as sentinel. 400 MCSectionData(); 401 MCSectionData(const MCSection &Section, MCAssembler *A = 0); 402 403 const MCSection &getSection() const { return *Section; } 404 405 unsigned getAlignment() const { return Alignment; } 406 void setAlignment(unsigned Value) { Alignment = Value; } 407 408 /// @name Fragment Access 409 /// @{ 410 411 const FragmentListType &getFragmentList() const { return Fragments; } 412 FragmentListType &getFragmentList() { return Fragments; } 413 414 iterator begin() { return Fragments.begin(); } 415 const_iterator begin() const { return Fragments.begin(); } 416 417 iterator end() { return Fragments.end(); } 418 const_iterator end() const { return Fragments.end(); } 419 420 reverse_iterator rbegin() { return Fragments.rbegin(); } 421 const_reverse_iterator rbegin() const { return Fragments.rbegin(); } 422 423 reverse_iterator rend() { return Fragments.rend(); } 424 const_reverse_iterator rend() const { return Fragments.rend(); } 425 426 size_t size() const { return Fragments.size(); } 427 428 bool empty() const { return Fragments.empty(); } 429 430 /// @} 431 /// @name Assembler Backend Support 432 /// @{ 433 // 434 // FIXME: This could all be kept private to the assembler implementation. 435 436 uint64_t getAddress() const { 437 assert(Address != ~UINT64_C(0) && "Address not set!"); 438 return Address; 439 } 440 void setAddress(uint64_t Value) { Address = Value; } 441 442 uint64_t getSize() const { 443 assert(Size != ~UINT64_C(0) && "File size not set!"); 444 return Size; 445 } 446 void setSize(uint64_t Value) { Size = Value; } 447 448 uint64_t getFileSize() const { 449 assert(FileSize != ~UINT64_C(0) && "File size not set!"); 450 return FileSize; 451 } 452 void setFileSize(uint64_t Value) { FileSize = Value; } 453 454 bool hasInstructions() const { return HasInstructions; } 455 void setHasInstructions(bool Value) { HasInstructions = Value; } 456 457 /// @} 458 459 void dump(); 460}; 461 462// FIXME: Same concerns as with SectionData. 463class MCSymbolData : public ilist_node<MCSymbolData> { 464public: 465 const MCSymbol *Symbol; 466 467 /// Fragment - The fragment this symbol's value is relative to, if any. 468 MCFragment *Fragment; 469 470 /// Offset - The offset to apply to the fragment address to form this symbol's 471 /// value. 472 uint64_t Offset; 473 474 /// IsExternal - True if this symbol is visible outside this translation 475 /// unit. 476 unsigned IsExternal : 1; 477 478 /// IsPrivateExtern - True if this symbol is private extern. 479 unsigned IsPrivateExtern : 1; 480 481 /// CommonSize - The size of the symbol, if it is 'common', or 0. 482 // 483 // FIXME: Pack this in with other fields? We could put it in offset, since a 484 // common symbol can never get a definition. 485 uint64_t CommonSize; 486 487 /// CommonAlign - The alignment of the symbol, if it is 'common'. 488 // 489 // FIXME: Pack this in with other fields? 490 unsigned CommonAlign; 491 492 /// Flags - The Flags field is used by object file implementations to store 493 /// additional per symbol information which is not easily classified. 494 uint32_t Flags; 495 496 /// Index - Index field, for use by the object file implementation. 497 uint64_t Index; 498 499public: 500 // Only for use as sentinel. 501 MCSymbolData(); 502 MCSymbolData(const MCSymbol &_Symbol, MCFragment *_Fragment, uint64_t _Offset, 503 MCAssembler *A = 0); 504 505 /// @name Accessors 506 /// @{ 507 508 const MCSymbol &getSymbol() const { return *Symbol; } 509 510 MCFragment *getFragment() const { return Fragment; } 511 void setFragment(MCFragment *Value) { Fragment = Value; } 512 513 uint64_t getOffset() const { return Offset; } 514 void setOffset(uint64_t Value) { Offset = Value; } 515 516 uint64_t getAddress() const { 517 assert(getFragment() && "Invalid getAddress() on undefined symbol!"); 518 return getFragment()->getAddress() + getOffset(); 519 } 520 521 /// @} 522 /// @name Symbol Attributes 523 /// @{ 524 525 bool isExternal() const { return IsExternal; } 526 void setExternal(bool Value) { IsExternal = Value; } 527 528 bool isPrivateExtern() const { return IsPrivateExtern; } 529 void setPrivateExtern(bool Value) { IsPrivateExtern = Value; } 530 531 /// isCommon - Is this a 'common' symbol. 532 bool isCommon() const { return CommonSize != 0; } 533 534 /// setCommon - Mark this symbol as being 'common'. 535 /// 536 /// \param Size - The size of the symbol. 537 /// \param Align - The alignment of the symbol. 538 void setCommon(uint64_t Size, unsigned Align) { 539 CommonSize = Size; 540 CommonAlign = Align; 541 } 542 543 /// getCommonSize - Return the size of a 'common' symbol. 544 uint64_t getCommonSize() const { 545 assert(isCommon() && "Not a 'common' symbol!"); 546 return CommonSize; 547 } 548 549 /// getCommonAlignment - Return the alignment of a 'common' symbol. 550 unsigned getCommonAlignment() const { 551 assert(isCommon() && "Not a 'common' symbol!"); 552 return CommonAlign; 553 } 554 555 /// getFlags - Get the (implementation defined) symbol flags. 556 uint32_t getFlags() const { return Flags; } 557 558 /// setFlags - Set the (implementation defined) symbol flags. 559 void setFlags(uint32_t Value) { Flags = Value; } 560 561 /// getIndex - Get the (implementation defined) index. 562 uint64_t getIndex() const { return Index; } 563 564 /// setIndex - Set the (implementation defined) index. 565 void setIndex(uint64_t Value) { Index = Value; } 566 567 /// @} 568 569 void dump(); 570}; 571 572// FIXME: This really doesn't belong here. See comments below. 573struct IndirectSymbolData { 574 MCSymbol *Symbol; 575 MCSectionData *SectionData; 576}; 577 578class MCAssembler { 579public: 580 typedef iplist<MCSectionData> SectionDataListType; 581 typedef iplist<MCSymbolData> SymbolDataListType; 582 583 typedef SectionDataListType::const_iterator const_iterator; 584 typedef SectionDataListType::iterator iterator; 585 586 typedef SymbolDataListType::const_iterator const_symbol_iterator; 587 typedef SymbolDataListType::iterator symbol_iterator; 588 589 typedef std::vector<IndirectSymbolData>::const_iterator 590 const_indirect_symbol_iterator; 591 typedef std::vector<IndirectSymbolData>::iterator indirect_symbol_iterator; 592 593private: 594 MCAssembler(const MCAssembler&); // DO NOT IMPLEMENT 595 void operator=(const MCAssembler&); // DO NOT IMPLEMENT 596 597 MCContext &Context; 598 599 TargetAsmBackend &Backend; 600 601 raw_ostream &OS; 602 603 iplist<MCSectionData> Sections; 604 605 iplist<MCSymbolData> Symbols; 606 607 /// The map of sections to their associated assembler backend data. 608 // 609 // FIXME: Avoid this indirection? 610 DenseMap<const MCSection*, MCSectionData*> SectionMap; 611 612 /// The map of symbols to their associated assembler backend data. 613 // 614 // FIXME: Avoid this indirection? 615 DenseMap<const MCSymbol*, MCSymbolData*> SymbolMap; 616 617 std::vector<IndirectSymbolData> IndirectSymbols; 618 619 unsigned SubsectionsViaSymbols : 1; 620 621private: 622 /// Evaluate a fixup to a relocatable expression and the value which should be 623 /// placed into the fixup. 624 /// 625 /// \param Layout The layout to use for evaluation. 626 /// \param Fixup The fixup to evaluate. 627 /// \param DF The fragment the fixup is inside. 628 /// \param Target [out] On return, the relocatable expression the fixup 629 /// evaluates to. 630 /// \param Value [out] On return, the value of the fixup as currently layed 631 /// out. 632 /// \return Whether the fixup value was fully resolved. This is true if the 633 /// \arg Value result is fixed, otherwise the value may change due to 634 /// relocation. 635 bool EvaluateFixup(const MCAsmLayout &Layout, 636 MCAsmFixup &Fixup, MCDataFragment *DF, 637 MCValue &Target, uint64_t &Value) const; 638 639 /// Check whether a fixup can be satisfied, or whether it needs to be relaxed 640 /// (increased in size, in order to hold its value correctly). 641 bool FixupNeedsRelaxation(MCAsmFixup &Fixup, MCDataFragment *DF); 642 643 /// LayoutSection - Assign offsets and sizes to the fragments in the section 644 /// \arg SD, and update the section size. The section file offset should 645 /// already have been computed. 646 void LayoutSection(MCSectionData &SD); 647 648 /// LayoutOnce - Perform one layout iteration and return true if any offsets 649 /// were adjusted. 650 bool LayoutOnce(); 651 652public: 653 /// Find the symbol which defines the atom containing given address, inside 654 /// the given section, or null if there is no such symbol. 655 // 656 // FIXME: Eliminate this, it is very slow. 657 const MCSymbolData *getAtomForAddress(const MCSectionData *Section, 658 uint64_t Address) const; 659 660 /// Find the symbol which defines the atom containing the given symbol, or 661 /// null if there is no such symbol. 662 // 663 // FIXME: Eliminate this, it is very slow. 664 const MCSymbolData *getAtom(const MCSymbolData *Symbol) const; 665 666 /// Check whether a particular symbol is visible to the linker and is required 667 /// in the symbol table, or whether it can be discarded by the assembler. This 668 /// also effects whether the assembler treats the label as potentially 669 /// defining a separate atom. 670 bool isSymbolLinkerVisible(const MCSymbolData *SD) const; 671 672 /// Emit the section contents using the given object writer. 673 // 674 // FIXME: Should MCAssembler always have a reference to the object writer? 675 void WriteSectionData(const MCSectionData *Section, MCObjectWriter *OW) const; 676 677public: 678 /// Construct a new assembler instance. 679 /// 680 /// \arg OS - The stream to output to. 681 // 682 // FIXME: How are we going to parameterize this? Two obvious options are stay 683 // concrete and require clients to pass in a target like object. The other 684 // option is to make this abstract, and have targets provide concrete 685 // implementations as we do with AsmParser. 686 MCAssembler(MCContext &_Context, TargetAsmBackend &_Backend, raw_ostream &OS); 687 ~MCAssembler(); 688 689 MCContext &getContext() const { return Context; } 690 691 TargetAsmBackend &getBackend() const { return Backend; } 692 693 /// Finish - Do final processing and write the object to the output stream. 694 void Finish(); 695 696 // FIXME: This does not belong here. 697 bool getSubsectionsViaSymbols() const { 698 return SubsectionsViaSymbols; 699 } 700 void setSubsectionsViaSymbols(bool Value) { 701 SubsectionsViaSymbols = Value; 702 } 703 704 /// @name Section List Access 705 /// @{ 706 707 const SectionDataListType &getSectionList() const { return Sections; } 708 SectionDataListType &getSectionList() { return Sections; } 709 710 iterator begin() { return Sections.begin(); } 711 const_iterator begin() const { return Sections.begin(); } 712 713 iterator end() { return Sections.end(); } 714 const_iterator end() const { return Sections.end(); } 715 716 size_t size() const { return Sections.size(); } 717 718 /// @} 719 /// @name Symbol List Access 720 /// @{ 721 722 const SymbolDataListType &getSymbolList() const { return Symbols; } 723 SymbolDataListType &getSymbolList() { return Symbols; } 724 725 symbol_iterator symbol_begin() { return Symbols.begin(); } 726 const_symbol_iterator symbol_begin() const { return Symbols.begin(); } 727 728 symbol_iterator symbol_end() { return Symbols.end(); } 729 const_symbol_iterator symbol_end() const { return Symbols.end(); } 730 731 size_t symbol_size() const { return Symbols.size(); } 732 733 /// @} 734 /// @name Indirect Symbol List Access 735 /// @{ 736 737 // FIXME: This is a total hack, this should not be here. Once things are 738 // factored so that the streamer has direct access to the .o writer, it can 739 // disappear. 740 std::vector<IndirectSymbolData> &getIndirectSymbols() { 741 return IndirectSymbols; 742 } 743 744 indirect_symbol_iterator indirect_symbol_begin() { 745 return IndirectSymbols.begin(); 746 } 747 const_indirect_symbol_iterator indirect_symbol_begin() const { 748 return IndirectSymbols.begin(); 749 } 750 751 indirect_symbol_iterator indirect_symbol_end() { 752 return IndirectSymbols.end(); 753 } 754 const_indirect_symbol_iterator indirect_symbol_end() const { 755 return IndirectSymbols.end(); 756 } 757 758 size_t indirect_symbol_size() const { return IndirectSymbols.size(); } 759 760 /// @} 761 /// @name Backend Data Access 762 /// @{ 763 764 MCSectionData &getSectionData(const MCSection &Section) const { 765 MCSectionData *Entry = SectionMap.lookup(&Section); 766 assert(Entry && "Missing section data!"); 767 return *Entry; 768 } 769 770 MCSectionData &getOrCreateSectionData(const MCSection &Section, 771 bool *Created = 0) { 772 MCSectionData *&Entry = SectionMap[&Section]; 773 774 if (Created) *Created = !Entry; 775 if (!Entry) 776 Entry = new MCSectionData(Section, this); 777 778 return *Entry; 779 } 780 781 MCSymbolData &getSymbolData(const MCSymbol &Symbol) const { 782 MCSymbolData *Entry = SymbolMap.lookup(&Symbol); 783 assert(Entry && "Missing symbol data!"); 784 return *Entry; 785 } 786 787 MCSymbolData &getOrCreateSymbolData(const MCSymbol &Symbol, 788 bool *Created = 0) { 789 MCSymbolData *&Entry = SymbolMap[&Symbol]; 790 791 if (Created) *Created = !Entry; 792 if (!Entry) 793 Entry = new MCSymbolData(Symbol, 0, 0, this); 794 795 return *Entry; 796 } 797 798 /// @} 799 800 void dump(); 801}; 802 803} // end namespace llvm 804 805#endif 806