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