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