MCAssembler.h revision c96a82a53415fd0b6cb1bbea2593dc18683c70cc
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/MC/MCInst.h" 20#include "llvm/System/DataTypes.h" 21#include <vector> // FIXME: Shouldn't be needed. 22 23namespace llvm { 24class raw_ostream; 25class MCAsmLayout; 26class MCAssembler; 27class MCContext; 28class MCCodeEmitter; 29class MCExpr; 30class MCFragment; 31class MCObjectWriter; 32class MCSection; 33class MCSectionData; 34class MCSymbol; 35class MCSymbolData; 36class MCValue; 37class TargetAsmBackend; 38 39class MCFragment : public ilist_node<MCFragment> { 40 friend class MCAsmLayout; 41 42 MCFragment(const MCFragment&); // DO NOT IMPLEMENT 43 void operator=(const MCFragment&); // DO NOT IMPLEMENT 44 45public: 46 enum FragmentType { 47 FT_Align, 48 FT_Data, 49 FT_Fill, 50 FT_Inst, 51 FT_Org 52 }; 53 54private: 55 FragmentType Kind; 56 57 /// Parent - The data for the section this fragment is in. 58 MCSectionData *Parent; 59 60 /// Atom - The atom this fragment is in, as represented by it's defining 61 /// symbol. Atom's are only used by backends which set 62 /// \see MCAsmBackend::hasReliableSymbolDifference(). 63 MCSymbolData *Atom; 64 65 /// @name Assembler Backend Data 66 /// @{ 67 // 68 // FIXME: This could all be kept private to the assembler implementation. 69 70 /// Offset - The offset of this fragment in its section. This is ~0 until 71 /// initialized. 72 uint64_t Offset; 73 74 /// EffectiveSize - The compute size of this section. This is ~0 until 75 /// initialized. 76 uint64_t EffectiveSize; 77 78 /// LayoutOrder - The global layout order of this fragment. This is the index 79 /// across all fragments in the file, not just within the section. 80 unsigned LayoutOrder; 81 82 /// @} 83 84protected: 85 MCFragment(FragmentType _Kind, MCSectionData *_Parent = 0); 86 87public: 88 // Only for sentinel. 89 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 /// InstSize - The size of 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 /// EmitNops - Flag to indicate that (optimal) NOPs should be emitted instead 231 /// of using the provided value. The exact interpretation of this flag is 232 /// target dependent. 233 bool EmitNops : 1; 234 235 /// OnlyAlignAddress - Flag to indicate that this align is only used to adjust 236 /// the address space size of a section and that it should not be included as 237 /// part of the section size. This flag can only be used on the last fragment 238 /// in a section. 239 bool OnlyAlignAddress : 1; 240 241public: 242 MCAlignFragment(unsigned _Alignment, int64_t _Value, unsigned _ValueSize, 243 unsigned _MaxBytesToEmit, MCSectionData *SD = 0) 244 : MCFragment(FT_Align, SD), Alignment(_Alignment), 245 Value(_Value),ValueSize(_ValueSize), 246 MaxBytesToEmit(_MaxBytesToEmit), EmitNops(false), 247 OnlyAlignAddress(false) {} 248 249 /// @name Accessors 250 /// @{ 251 252 unsigned getAlignment() const { return Alignment; } 253 254 int64_t getValue() const { return Value; } 255 256 unsigned getValueSize() const { return ValueSize; } 257 258 unsigned getMaxBytesToEmit() const { return MaxBytesToEmit; } 259 260 bool hasEmitNops() const { return EmitNops; } 261 void setEmitNops(bool Value) { EmitNops = Value; } 262 263 bool hasOnlyAlignAddress() const { return OnlyAlignAddress; } 264 void setOnlyAlignAddress(bool Value) { OnlyAlignAddress = Value; } 265 266 /// @} 267 268 static bool classof(const MCFragment *F) { 269 return F->getKind() == MCFragment::FT_Align; 270 } 271 static bool classof(const MCAlignFragment *) { return true; } 272}; 273 274class MCFillFragment : public MCFragment { 275 /// Value - Value to use for filling bytes. 276 int64_t Value; 277 278 /// ValueSize - The size (in bytes) of \arg Value to use when filling, or 0 if 279 /// this is a virtual fill fragment. 280 unsigned ValueSize; 281 282 /// Size - The number of bytes to insert. 283 uint64_t Size; 284 285public: 286 MCFillFragment(int64_t _Value, unsigned _ValueSize, uint64_t _Size, 287 MCSectionData *SD = 0) 288 : MCFragment(FT_Fill, SD), 289 Value(_Value), ValueSize(_ValueSize), Size(_Size) { 290 assert((!ValueSize || (Size % ValueSize) == 0) && 291 "Fill size must be a multiple of the value size!"); 292 } 293 294 /// @name Accessors 295 /// @{ 296 297 int64_t getValue() const { return Value; } 298 299 unsigned getValueSize() const { return ValueSize; } 300 301 uint64_t getSize() const { return Size; } 302 303 /// @} 304 305 static bool classof(const MCFragment *F) { 306 return F->getKind() == MCFragment::FT_Fill; 307 } 308 static bool classof(const MCFillFragment *) { return true; } 309}; 310 311class MCOrgFragment : public MCFragment { 312 /// Offset - The offset this fragment should start at. 313 const MCExpr *Offset; 314 315 /// Value - Value to use for filling bytes. 316 int8_t Value; 317 318public: 319 MCOrgFragment(const MCExpr &_Offset, int8_t _Value, MCSectionData *SD = 0) 320 : MCFragment(FT_Org, SD), 321 Offset(&_Offset), Value(_Value) {} 322 323 /// @name Accessors 324 /// @{ 325 326 const MCExpr &getOffset() const { return *Offset; } 327 328 uint8_t getValue() const { return Value; } 329 330 /// @} 331 332 static bool classof(const MCFragment *F) { 333 return F->getKind() == MCFragment::FT_Org; 334 } 335 static bool classof(const MCOrgFragment *) { return true; } 336}; 337 338// FIXME: Should this be a separate class, or just merged into MCSection? Since 339// we anticipate the fast path being through an MCAssembler, the only reason to 340// keep it out is for API abstraction. 341class MCSectionData : public ilist_node<MCSectionData> { 342 friend class MCAsmLayout; 343 344 MCSectionData(const MCSectionData&); // DO NOT IMPLEMENT 345 void operator=(const MCSectionData&); // DO NOT IMPLEMENT 346 347public: 348 typedef iplist<MCFragment> FragmentListType; 349 350 typedef FragmentListType::const_iterator const_iterator; 351 typedef FragmentListType::iterator iterator; 352 353 typedef FragmentListType::const_reverse_iterator const_reverse_iterator; 354 typedef FragmentListType::reverse_iterator reverse_iterator; 355 356private: 357 FragmentListType Fragments; 358 const MCSection *Section; 359 360 /// Ordinal - The section index in the assemblers section list. 361 unsigned Ordinal; 362 363 /// LayoutOrder - The index of this section in the layout order. 364 unsigned LayoutOrder; 365 366 /// Alignment - The maximum alignment seen in this section. 367 unsigned Alignment; 368 369 /// @name Assembler Backend Data 370 /// @{ 371 // 372 // FIXME: This could all be kept private to the assembler implementation. 373 374 /// Address - The computed address of this section. This is ~0 until 375 /// initialized. 376 uint64_t Address; 377 378 /// HasInstructions - Whether this section has had instructions emitted into 379 /// it. 380 unsigned HasInstructions : 1; 381 382 /// @} 383 384public: 385 // Only for use as sentinel. 386 MCSectionData(); 387 MCSectionData(const MCSection &Section, MCAssembler *A = 0); 388 389 const MCSection &getSection() const { return *Section; } 390 391 unsigned getAlignment() const { return Alignment; } 392 void setAlignment(unsigned Value) { Alignment = Value; } 393 394 bool hasInstructions() const { return HasInstructions; } 395 void setHasInstructions(bool Value) { HasInstructions = Value; } 396 397 unsigned getOrdinal() const { return Ordinal; } 398 void setOrdinal(unsigned Value) { Ordinal = Value; } 399 400 unsigned getLayoutOrder() const { return LayoutOrder; } 401 void setLayoutOrder(unsigned Value) { LayoutOrder = Value; } 402 403 /// @name Fragment Access 404 /// @{ 405 406 const FragmentListType &getFragmentList() const { return Fragments; } 407 FragmentListType &getFragmentList() { return Fragments; } 408 409 iterator begin() { return Fragments.begin(); } 410 const_iterator begin() const { return Fragments.begin(); } 411 412 iterator end() { return Fragments.end(); } 413 const_iterator end() const { return Fragments.end(); } 414 415 reverse_iterator rbegin() { return Fragments.rbegin(); } 416 const_reverse_iterator rbegin() const { return Fragments.rbegin(); } 417 418 reverse_iterator rend() { return Fragments.rend(); } 419 const_reverse_iterator rend() const { return Fragments.rend(); } 420 421 size_t size() const { return Fragments.size(); } 422 423 bool empty() const { return Fragments.empty(); } 424 425 void dump(); 426 427 /// @} 428}; 429 430// FIXME: Same concerns as with SectionData. 431class MCSymbolData : public ilist_node<MCSymbolData> { 432public: 433 const MCSymbol *Symbol; 434 435 /// Fragment - The fragment this symbol's value is relative to, if any. 436 MCFragment *Fragment; 437 438 /// Offset - The offset to apply to the fragment address to form this symbol's 439 /// value. 440 uint64_t Offset; 441 442 /// IsExternal - True if this symbol is visible outside this translation 443 /// unit. 444 unsigned IsExternal : 1; 445 446 /// IsPrivateExtern - True if this symbol is private extern. 447 unsigned IsPrivateExtern : 1; 448 449 /// CommonSize - The size of the symbol, if it is 'common', or 0. 450 // 451 // FIXME: Pack this in with other fields? We could put it in offset, since a 452 // common symbol can never get a definition. 453 uint64_t CommonSize; 454 455 /// CommonAlign - The alignment of the symbol, if it is 'common'. 456 // 457 // FIXME: Pack this in with other fields? 458 unsigned CommonAlign; 459 460 /// Flags - The Flags field is used by object file implementations to store 461 /// additional per symbol information which is not easily classified. 462 uint32_t Flags; 463 464 /// Index - Index field, for use by the object file implementation. 465 uint64_t Index; 466 467public: 468 // Only for use as sentinel. 469 MCSymbolData(); 470 MCSymbolData(const MCSymbol &_Symbol, MCFragment *_Fragment, uint64_t _Offset, 471 MCAssembler *A = 0); 472 473 /// @name Accessors 474 /// @{ 475 476 const MCSymbol &getSymbol() const { return *Symbol; } 477 478 MCFragment *getFragment() const { return Fragment; } 479 void setFragment(MCFragment *Value) { Fragment = Value; } 480 481 uint64_t getOffset() const { return Offset; } 482 void setOffset(uint64_t Value) { Offset = Value; } 483 484 /// @} 485 /// @name Symbol Attributes 486 /// @{ 487 488 bool isExternal() const { return IsExternal; } 489 void setExternal(bool Value) { IsExternal = Value; } 490 491 bool isPrivateExtern() const { return IsPrivateExtern; } 492 void setPrivateExtern(bool Value) { IsPrivateExtern = Value; } 493 494 /// isCommon - Is this a 'common' symbol. 495 bool isCommon() const { return CommonSize != 0; } 496 497 /// setCommon - Mark this symbol as being 'common'. 498 /// 499 /// \param Size - The size of the symbol. 500 /// \param Align - The alignment of the symbol. 501 void setCommon(uint64_t Size, unsigned Align) { 502 CommonSize = Size; 503 CommonAlign = Align; 504 } 505 506 /// getCommonSize - Return the size of a 'common' symbol. 507 uint64_t getCommonSize() const { 508 assert(isCommon() && "Not a 'common' symbol!"); 509 return CommonSize; 510 } 511 512 /// getCommonAlignment - Return the alignment of a 'common' symbol. 513 unsigned getCommonAlignment() const { 514 assert(isCommon() && "Not a 'common' symbol!"); 515 return CommonAlign; 516 } 517 518 /// getFlags - Get the (implementation defined) symbol flags. 519 uint32_t getFlags() const { return Flags; } 520 521 /// setFlags - Set the (implementation defined) symbol flags. 522 void setFlags(uint32_t Value) { Flags = Value; } 523 524 /// modifyFlags - Modify the flags via a mask 525 void modifyFlags(uint32_t Value, uint32_t Mask) { 526 Flags = (Flags & ~Mask) | Value; 527 } 528 529 /// getIndex - Get the (implementation defined) index. 530 uint64_t getIndex() const { return Index; } 531 532 /// setIndex - Set the (implementation defined) index. 533 void setIndex(uint64_t Value) { Index = Value; } 534 535 /// @} 536 537 void dump(); 538}; 539 540// FIXME: This really doesn't belong here. See comments below. 541struct IndirectSymbolData { 542 MCSymbol *Symbol; 543 MCSectionData *SectionData; 544}; 545 546class MCAssembler { 547 friend class MCAsmLayout; 548 549public: 550 typedef iplist<MCSectionData> SectionDataListType; 551 typedef iplist<MCSymbolData> SymbolDataListType; 552 553 typedef SectionDataListType::const_iterator const_iterator; 554 typedef SectionDataListType::iterator iterator; 555 556 typedef SymbolDataListType::const_iterator const_symbol_iterator; 557 typedef SymbolDataListType::iterator symbol_iterator; 558 559 typedef std::vector<IndirectSymbolData>::const_iterator 560 const_indirect_symbol_iterator; 561 typedef std::vector<IndirectSymbolData>::iterator indirect_symbol_iterator; 562 563private: 564 MCAssembler(const MCAssembler&); // DO NOT IMPLEMENT 565 void operator=(const MCAssembler&); // DO NOT IMPLEMENT 566 567 MCContext &Context; 568 569 TargetAsmBackend &Backend; 570 571 MCCodeEmitter &Emitter; 572 573 raw_ostream &OS; 574 575 iplist<MCSectionData> Sections; 576 577 iplist<MCSymbolData> Symbols; 578 579 /// The map of sections to their associated assembler backend data. 580 // 581 // FIXME: Avoid this indirection? 582 DenseMap<const MCSection*, MCSectionData*> SectionMap; 583 584 /// The map of symbols to their associated assembler backend data. 585 // 586 // FIXME: Avoid this indirection? 587 DenseMap<const MCSymbol*, MCSymbolData*> SymbolMap; 588 589 std::vector<IndirectSymbolData> IndirectSymbols; 590 591 unsigned RelaxAll : 1; 592 unsigned SubsectionsViaSymbols : 1; 593 594private: 595 /// Evaluate a fixup to a relocatable expression and the value which should be 596 /// placed into the fixup. 597 /// 598 /// \param Layout The layout to use for evaluation. 599 /// \param Fixup The fixup to evaluate. 600 /// \param DF The fragment the fixup is inside. 601 /// \param Target [out] On return, the relocatable expression the fixup 602 /// evaluates to. 603 /// \param Value [out] On return, the value of the fixup as currently layed 604 /// out. 605 /// \return Whether the fixup value was fully resolved. This is true if the 606 /// \arg Value result is fixed, otherwise the value may change due to 607 /// relocation. 608 bool EvaluateFixup(const MCAsmLayout &Layout, 609 const MCFixup &Fixup, const MCFragment *DF, 610 MCValue &Target, uint64_t &Value) const; 611 612 /// Check whether a fixup can be satisfied, or whether it needs to be relaxed 613 /// (increased in size, in order to hold its value correctly). 614 bool FixupNeedsRelaxation(const MCFixup &Fixup, const MCFragment *DF, 615 const MCAsmLayout &Layout) const; 616 617 /// Check whether the given fragment needs relaxation. 618 bool FragmentNeedsRelaxation(const MCInstFragment *IF, 619 const MCAsmLayout &Layout) const; 620 621 /// Compute the effective fragment size assuming it is layed out at the given 622 /// \arg SectionAddress and \arg FragmentOffset. 623 uint64_t ComputeFragmentSize(MCAsmLayout &Layout, const MCFragment &F, 624 uint64_t SectionAddress, 625 uint64_t FragmentOffset) const; 626 627 /// LayoutOnce - Perform one layout iteration and return true if any offsets 628 /// were adjusted. 629 bool LayoutOnce(MCAsmLayout &Layout); 630 631 /// FinishLayout - Finalize a layout, including fragment lowering. 632 void FinishLayout(MCAsmLayout &Layout); 633 634public: 635 /// Find the symbol which defines the atom containing the given symbol, or 636 /// null if there is no such symbol. 637 const MCSymbolData *getAtom(const MCAsmLayout &Layout, 638 const MCSymbolData *Symbol) const; 639 640 /// Check whether a particular symbol is visible to the linker and is required 641 /// in the symbol table, or whether it can be discarded by the assembler. This 642 /// also effects whether the assembler treats the label as potentially 643 /// defining a separate atom. 644 bool isSymbolLinkerVisible(const MCSymbol &SD) const; 645 646 /// Emit the section contents using the given object writer. 647 // 648 // FIXME: Should MCAssembler always have a reference to the object writer? 649 void WriteSectionData(const MCSectionData *Section, const MCAsmLayout &Layout, 650 MCObjectWriter *OW) const; 651 652public: 653 /// Construct a new assembler instance. 654 /// 655 /// \arg OS - The stream to output to. 656 // 657 // FIXME: How are we going to parameterize this? Two obvious options are stay 658 // concrete and require clients to pass in a target like object. The other 659 // option is to make this abstract, and have targets provide concrete 660 // implementations as we do with AsmParser. 661 MCAssembler(MCContext &_Context, TargetAsmBackend &_Backend, 662 MCCodeEmitter &_Emitter, raw_ostream &OS); 663 ~MCAssembler(); 664 665 MCContext &getContext() const { return Context; } 666 667 TargetAsmBackend &getBackend() const { return Backend; } 668 669 MCCodeEmitter &getEmitter() const { return Emitter; } 670 671 /// Finish - Do final processing and write the object to the output stream. 672 /// \arg Writer is used for custom object writer (as the MCJIT does), 673 /// if not specified it is automatically created from backend. 674 void Finish(MCObjectWriter *Writer = 0); 675 676 // FIXME: This does not belong here. 677 bool getSubsectionsViaSymbols() const { 678 return SubsectionsViaSymbols; 679 } 680 void setSubsectionsViaSymbols(bool Value) { 681 SubsectionsViaSymbols = Value; 682 } 683 684 bool getRelaxAll() const { return RelaxAll; } 685 void setRelaxAll(bool Value) { RelaxAll = Value; } 686 687 /// @name Section List Access 688 /// @{ 689 690 const SectionDataListType &getSectionList() const { return Sections; } 691 SectionDataListType &getSectionList() { return Sections; } 692 693 iterator begin() { return Sections.begin(); } 694 const_iterator begin() const { return Sections.begin(); } 695 696 iterator end() { return Sections.end(); } 697 const_iterator end() const { return Sections.end(); } 698 699 size_t size() const { return Sections.size(); } 700 701 /// @} 702 /// @name Symbol List Access 703 /// @{ 704 705 const SymbolDataListType &getSymbolList() const { return Symbols; } 706 SymbolDataListType &getSymbolList() { return Symbols; } 707 708 symbol_iterator symbol_begin() { return Symbols.begin(); } 709 const_symbol_iterator symbol_begin() const { return Symbols.begin(); } 710 711 symbol_iterator symbol_end() { return Symbols.end(); } 712 const_symbol_iterator symbol_end() const { return Symbols.end(); } 713 714 size_t symbol_size() const { return Symbols.size(); } 715 716 /// @} 717 /// @name Indirect Symbol List Access 718 /// @{ 719 720 // FIXME: This is a total hack, this should not be here. Once things are 721 // factored so that the streamer has direct access to the .o writer, it can 722 // disappear. 723 std::vector<IndirectSymbolData> &getIndirectSymbols() { 724 return IndirectSymbols; 725 } 726 727 indirect_symbol_iterator indirect_symbol_begin() { 728 return IndirectSymbols.begin(); 729 } 730 const_indirect_symbol_iterator indirect_symbol_begin() const { 731 return IndirectSymbols.begin(); 732 } 733 734 indirect_symbol_iterator indirect_symbol_end() { 735 return IndirectSymbols.end(); 736 } 737 const_indirect_symbol_iterator indirect_symbol_end() const { 738 return IndirectSymbols.end(); 739 } 740 741 size_t indirect_symbol_size() const { return IndirectSymbols.size(); } 742 743 /// @} 744 /// @name Backend Data Access 745 /// @{ 746 747 MCSectionData &getSectionData(const MCSection &Section) const { 748 MCSectionData *Entry = SectionMap.lookup(&Section); 749 assert(Entry && "Missing section data!"); 750 return *Entry; 751 } 752 753 MCSectionData &getOrCreateSectionData(const MCSection &Section, 754 bool *Created = 0) { 755 MCSectionData *&Entry = SectionMap[&Section]; 756 757 if (Created) *Created = !Entry; 758 if (!Entry) 759 Entry = new MCSectionData(Section, this); 760 761 return *Entry; 762 } 763 764 MCSymbolData &getSymbolData(const MCSymbol &Symbol) const { 765 MCSymbolData *Entry = SymbolMap.lookup(&Symbol); 766 assert(Entry && "Missing symbol data!"); 767 return *Entry; 768 } 769 770 MCSymbolData &getOrCreateSymbolData(const MCSymbol &Symbol, 771 bool *Created = 0) { 772 MCSymbolData *&Entry = SymbolMap[&Symbol]; 773 774 if (Created) *Created = !Entry; 775 if (!Entry) 776 Entry = new MCSymbolData(Symbol, 0, 0, this); 777 778 return *Entry; 779 } 780 781 /// @} 782 783 void dump(); 784}; 785 786} // end namespace llvm 787 788#endif 789