MCAssembler.h revision a8bf473fb15bbedc78144ec57438f884616283b0
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 MCBinaryExpr;
28class MCContext;
29class MCCodeEmitter;
30class MCExpr;
31class MCFragment;
32class MCObjectWriter;
33class MCSection;
34class MCSectionData;
35class MCSymbol;
36class MCSymbolData;
37class MCValue;
38class TargetAsmBackend;
39
40class MCFragment : public ilist_node<MCFragment> {
41  friend class MCAsmLayout;
42
43  MCFragment(const MCFragment&);     // DO NOT IMPLEMENT
44  void operator=(const MCFragment&); // DO NOT IMPLEMENT
45
46public:
47  enum FragmentType {
48    FT_Align,
49    FT_Data,
50    FT_Fill,
51    FT_Inst,
52    FT_Org
53  };
54
55private:
56  FragmentType Kind;
57
58  /// Parent - The data for the section this fragment is in.
59  MCSectionData *Parent;
60
61  /// Atom - The atom this fragment is in, as represented by it's defining
62  /// symbol. Atom's are only used by backends which set
63  /// \see MCAsmBackend::hasReliableSymbolDifference().
64  MCSymbolData *Atom;
65
66  /// @name Assembler Backend Data
67  /// @{
68  //
69  // FIXME: This could all be kept private to the assembler implementation.
70
71  /// Offset - The offset of this fragment in its section. This is ~0 until
72  /// initialized.
73  uint64_t Offset;
74
75  /// EffectiveSize - The compute size of this section. This is ~0 until
76  /// initialized.
77  uint64_t EffectiveSize;
78
79  /// LayoutOrder - The global layout order of this fragment. This is the index
80  /// across all fragments in the file, not just within the section.
81  unsigned LayoutOrder;
82
83  /// @}
84
85protected:
86  MCFragment(FragmentType _Kind, MCSectionData *_Parent = 0);
87
88public:
89  // Only for sentinel.
90  MCFragment();
91  virtual ~MCFragment();
92
93  FragmentType getKind() const { return Kind; }
94
95  MCSectionData *getParent() const { return Parent; }
96  void setParent(MCSectionData *Value) { Parent = Value; }
97
98  MCSymbolData *getAtom() const { return Atom; }
99  void setAtom(MCSymbolData *Value) { Atom = Value; }
100
101  unsigned getLayoutOrder() const { return LayoutOrder; }
102  void setLayoutOrder(unsigned Value) { LayoutOrder = Value; }
103
104  static bool classof(const MCFragment *O) { return true; }
105
106  void dump();
107};
108
109class MCDataFragment : public MCFragment {
110  SmallString<32> Contents;
111
112  /// Fixups - The list of fixups in this fragment.
113  std::vector<MCFixup> Fixups;
114
115public:
116  typedef std::vector<MCFixup>::const_iterator const_fixup_iterator;
117  typedef std::vector<MCFixup>::iterator fixup_iterator;
118
119public:
120  MCDataFragment(MCSectionData *SD = 0) : MCFragment(FT_Data, SD) {}
121
122  /// @name Accessors
123  /// @{
124
125  SmallString<32> &getContents() { return Contents; }
126  const SmallString<32> &getContents() const { return Contents; }
127
128  /// @}
129  /// @name Fixup Access
130  /// @{
131
132  void addFixup(MCFixup Fixup) {
133    // Enforce invariant that fixups are in offset order.
134    assert((Fixups.empty() || Fixup.getOffset() > Fixups.back().getOffset()) &&
135           "Fixups must be added in order!");
136    Fixups.push_back(Fixup);
137  }
138
139  std::vector<MCFixup> &getFixups() { return Fixups; }
140  const std::vector<MCFixup> &getFixups() const { return Fixups; }
141
142  fixup_iterator fixup_begin() { return Fixups.begin(); }
143  const_fixup_iterator fixup_begin() const { return Fixups.begin(); }
144
145  fixup_iterator fixup_end() {return Fixups.end();}
146  const_fixup_iterator fixup_end() const {return Fixups.end();}
147
148  size_t fixup_size() const { return Fixups.size(); }
149
150  /// @}
151
152  static bool classof(const MCFragment *F) {
153    return F->getKind() == MCFragment::FT_Data;
154  }
155  static bool classof(const MCDataFragment *) { return true; }
156};
157
158// FIXME: This current incarnation of MCInstFragment doesn't make much sense, as
159// it is almost entirely a duplicate of MCDataFragment. If we decide to stick
160// with this approach (as opposed to making MCInstFragment a very light weight
161// object with just the MCInst and a code size, then we should just change
162// MCDataFragment to have an optional MCInst at its end.
163class MCInstFragment : public MCFragment {
164  /// Inst - The instruction this is a fragment for.
165  MCInst Inst;
166
167  /// InstSize - The size of the currently encoded instruction.
168  SmallString<8> Code;
169
170  /// Fixups - The list of fixups in this fragment.
171  SmallVector<MCFixup, 1> Fixups;
172
173public:
174  typedef SmallVectorImpl<MCFixup>::const_iterator const_fixup_iterator;
175  typedef SmallVectorImpl<MCFixup>::iterator fixup_iterator;
176
177public:
178  MCInstFragment(MCInst _Inst, MCSectionData *SD = 0)
179    : MCFragment(FT_Inst, SD), Inst(_Inst) {
180  }
181
182  /// @name Accessors
183  /// @{
184
185  SmallVectorImpl<char> &getCode() { return Code; }
186  const SmallVectorImpl<char> &getCode() const { return Code; }
187
188  unsigned getInstSize() const { return Code.size(); }
189
190  MCInst &getInst() { return Inst; }
191  const MCInst &getInst() const { return Inst; }
192
193  void setInst(MCInst Value) { Inst = Value; }
194
195  /// @}
196  /// @name Fixup Access
197  /// @{
198
199  SmallVectorImpl<MCFixup> &getFixups() { return Fixups; }
200  const SmallVectorImpl<MCFixup> &getFixups() const { return Fixups; }
201
202  fixup_iterator fixup_begin() { return Fixups.begin(); }
203  const_fixup_iterator fixup_begin() const { return Fixups.begin(); }
204
205  fixup_iterator fixup_end() {return Fixups.end();}
206  const_fixup_iterator fixup_end() const {return Fixups.end();}
207
208  size_t fixup_size() const { return Fixups.size(); }
209
210  /// @}
211
212  static bool classof(const MCFragment *F) {
213    return F->getKind() == MCFragment::FT_Inst;
214  }
215  static bool classof(const MCInstFragment *) { return true; }
216};
217
218class MCAlignFragment : public MCFragment {
219  /// Alignment - The alignment to ensure, in bytes.
220  unsigned Alignment;
221
222  /// Value - Value to use for filling padding bytes.
223  int64_t Value;
224
225  /// ValueSize - The size of the integer (in bytes) of \arg Value.
226  unsigned ValueSize;
227
228  /// MaxBytesToEmit - The maximum number of bytes to emit; if the alignment
229  /// cannot be satisfied in this width then this fragment is ignored.
230  unsigned MaxBytesToEmit;
231
232  /// EmitNops - Flag to indicate that (optimal) NOPs should be emitted instead
233  /// of using the provided value. The exact interpretation of this flag is
234  /// target dependent.
235  bool EmitNops : 1;
236
237  /// OnlyAlignAddress - Flag to indicate that this align is only used to adjust
238  /// the address space size of a section and that it should not be included as
239  /// part of the section size. This flag can only be used on the last fragment
240  /// in a section.
241  bool OnlyAlignAddress : 1;
242
243public:
244  MCAlignFragment(unsigned _Alignment, int64_t _Value, unsigned _ValueSize,
245                  unsigned _MaxBytesToEmit, MCSectionData *SD = 0)
246    : MCFragment(FT_Align, SD), Alignment(_Alignment),
247      Value(_Value),ValueSize(_ValueSize),
248      MaxBytesToEmit(_MaxBytesToEmit), EmitNops(false),
249      OnlyAlignAddress(false) {}
250
251  /// @name Accessors
252  /// @{
253
254  unsigned getAlignment() const { return Alignment; }
255
256  int64_t getValue() const { return Value; }
257
258  unsigned getValueSize() const { return ValueSize; }
259
260  unsigned getMaxBytesToEmit() const { return MaxBytesToEmit; }
261
262  bool hasEmitNops() const { return EmitNops; }
263  void setEmitNops(bool Value) { EmitNops = Value; }
264
265  bool hasOnlyAlignAddress() const { return OnlyAlignAddress; }
266  void setOnlyAlignAddress(bool Value) { OnlyAlignAddress = Value; }
267
268  /// @}
269
270  static bool classof(const MCFragment *F) {
271    return F->getKind() == MCFragment::FT_Align;
272  }
273  static bool classof(const MCAlignFragment *) { return true; }
274};
275
276class MCFillFragment : public MCFragment {
277  /// Value - Value to use for filling bytes.
278  int64_t Value;
279
280  /// ValueSize - The size (in bytes) of \arg Value to use when filling, or 0 if
281  /// this is a virtual fill fragment.
282  unsigned ValueSize;
283
284  /// Size - The number of bytes to insert.
285  uint64_t Size;
286
287public:
288  MCFillFragment(int64_t _Value, unsigned _ValueSize, uint64_t _Size,
289                 MCSectionData *SD = 0)
290    : MCFragment(FT_Fill, SD),
291      Value(_Value), ValueSize(_ValueSize), Size(_Size) {
292    assert((!ValueSize || (Size % ValueSize) == 0) &&
293           "Fill size must be a multiple of the value size!");
294  }
295
296  /// @name Accessors
297  /// @{
298
299  int64_t getValue() const { return Value; }
300
301  unsigned getValueSize() const { return ValueSize; }
302
303  uint64_t getSize() const { return Size; }
304
305  /// @}
306
307  static bool classof(const MCFragment *F) {
308    return F->getKind() == MCFragment::FT_Fill;
309  }
310  static bool classof(const MCFillFragment *) { return true; }
311};
312
313class MCOrgFragment : public MCFragment {
314  /// Offset - The offset this fragment should start at.
315  const MCExpr *Offset;
316
317  /// Value - Value to use for filling bytes.
318  int8_t Value;
319
320public:
321  MCOrgFragment(const MCExpr &_Offset, int8_t _Value, MCSectionData *SD = 0)
322    : MCFragment(FT_Org, SD),
323      Offset(&_Offset), Value(_Value) {}
324
325  /// @name Accessors
326  /// @{
327
328  const MCExpr &getOffset() const { return *Offset; }
329
330  uint8_t getValue() const { return Value; }
331
332  /// @}
333
334  static bool classof(const MCFragment *F) {
335    return F->getKind() == MCFragment::FT_Org;
336  }
337  static bool classof(const MCOrgFragment *) { return true; }
338};
339
340// FIXME: Should this be a separate class, or just merged into MCSection? Since
341// we anticipate the fast path being through an MCAssembler, the only reason to
342// keep it out is for API abstraction.
343class MCSectionData : public ilist_node<MCSectionData> {
344  friend class MCAsmLayout;
345
346  MCSectionData(const MCSectionData&);  // DO NOT IMPLEMENT
347  void operator=(const MCSectionData&); // DO NOT IMPLEMENT
348
349public:
350  typedef iplist<MCFragment> FragmentListType;
351
352  typedef FragmentListType::const_iterator const_iterator;
353  typedef FragmentListType::iterator iterator;
354
355  typedef FragmentListType::const_reverse_iterator const_reverse_iterator;
356  typedef FragmentListType::reverse_iterator reverse_iterator;
357
358private:
359  FragmentListType Fragments;
360  const MCSection *Section;
361
362  /// Ordinal - The section index in the assemblers section list.
363  unsigned Ordinal;
364
365  /// LayoutOrder - The index of this section in the layout order.
366  unsigned LayoutOrder;
367
368  /// Alignment - The maximum alignment seen in this section.
369  unsigned Alignment;
370
371  /// @name Assembler Backend Data
372  /// @{
373  //
374  // FIXME: This could all be kept private to the assembler implementation.
375
376  /// Address - The computed address of this section. This is ~0 until
377  /// initialized.
378  uint64_t Address;
379
380  /// HasInstructions - Whether this section has had instructions emitted into
381  /// it.
382  unsigned HasInstructions : 1;
383
384  /// @}
385
386public:
387  // Only for use as sentinel.
388  MCSectionData();
389  MCSectionData(const MCSection &Section, MCAssembler *A = 0);
390
391  const MCSection &getSection() const { return *Section; }
392
393  unsigned getAlignment() const { return Alignment; }
394  void setAlignment(unsigned Value) { Alignment = Value; }
395
396  bool hasInstructions() const { return HasInstructions; }
397  void setHasInstructions(bool Value) { HasInstructions = Value; }
398
399  unsigned getOrdinal() const { return Ordinal; }
400  void setOrdinal(unsigned Value) { Ordinal = Value; }
401
402  unsigned getLayoutOrder() const { return LayoutOrder; }
403  void setLayoutOrder(unsigned Value) { LayoutOrder = Value; }
404
405  /// @name Fragment Access
406  /// @{
407
408  const FragmentListType &getFragmentList() const { return Fragments; }
409  FragmentListType &getFragmentList() { return Fragments; }
410
411  iterator begin() { return Fragments.begin(); }
412  const_iterator begin() const { return Fragments.begin(); }
413
414  iterator end() { return Fragments.end(); }
415  const_iterator end() const { return Fragments.end(); }
416
417  reverse_iterator rbegin() { return Fragments.rbegin(); }
418  const_reverse_iterator rbegin() const { return Fragments.rbegin(); }
419
420  reverse_iterator rend() { return Fragments.rend(); }
421  const_reverse_iterator rend() const { return Fragments.rend(); }
422
423  size_t size() const { return Fragments.size(); }
424
425  bool empty() const { return Fragments.empty(); }
426
427  void dump();
428
429  /// @}
430};
431
432// FIXME: Same concerns as with SectionData.
433class MCSymbolData : public ilist_node<MCSymbolData> {
434public:
435  const MCSymbol *Symbol;
436
437  /// Fragment - The fragment this symbol's value is relative to, if any.
438  MCFragment *Fragment;
439
440  /// Offset - The offset to apply to the fragment address to form this symbol's
441  /// value.
442  uint64_t Offset;
443
444  /// IsExternal - True if this symbol is visible outside this translation
445  /// unit.
446  unsigned IsExternal : 1;
447
448  /// IsPrivateExtern - True if this symbol is private extern.
449  unsigned IsPrivateExtern : 1;
450
451  /// CommonSize - The size of the symbol, if it is 'common', or 0.
452  //
453  // FIXME: Pack this in with other fields? We could put it in offset, since a
454  // common symbol can never get a definition.
455  uint64_t CommonSize;
456
457  /// SymbolSize - An expression describing how to calculate the size of
458  /// a symbol. If a symbol has no size this field will be NULL.
459  const MCExpr *SymbolSize;
460
461  /// CommonAlign - The alignment of the symbol, if it is 'common'.
462  //
463  // FIXME: Pack this in with other fields?
464  unsigned CommonAlign;
465
466  /// Flags - The Flags field is used by object file implementations to store
467  /// additional per symbol information which is not easily classified.
468  uint32_t Flags;
469
470  /// Index - Index field, for use by the object file implementation.
471  uint64_t Index;
472
473public:
474  // Only for use as sentinel.
475  MCSymbolData();
476  MCSymbolData(const MCSymbol &_Symbol, MCFragment *_Fragment, uint64_t _Offset,
477               MCAssembler *A = 0);
478
479  /// @name Accessors
480  /// @{
481
482  const MCSymbol &getSymbol() const { return *Symbol; }
483
484  MCFragment *getFragment() const { return Fragment; }
485  void setFragment(MCFragment *Value) { Fragment = Value; }
486
487  uint64_t getOffset() const { return Offset; }
488  void setOffset(uint64_t Value) { Offset = Value; }
489
490  /// @}
491  /// @name Symbol Attributes
492  /// @{
493
494  bool isExternal() const { return IsExternal; }
495  void setExternal(bool Value) { IsExternal = Value; }
496
497  bool isPrivateExtern() const { return IsPrivateExtern; }
498  void setPrivateExtern(bool Value) { IsPrivateExtern = Value; }
499
500  /// isCommon - Is this a 'common' symbol.
501  bool isCommon() const { return CommonSize != 0; }
502
503  /// setCommon - Mark this symbol as being 'common'.
504  ///
505  /// \param Size - The size of the symbol.
506  /// \param Align - The alignment of the symbol.
507  void setCommon(uint64_t Size, unsigned Align) {
508    CommonSize = Size;
509    CommonAlign = Align;
510  }
511
512  /// getCommonSize - Return the size of a 'common' symbol.
513  uint64_t getCommonSize() const {
514    assert(isCommon() && "Not a 'common' symbol!");
515    return CommonSize;
516  }
517
518  void setSize(const MCExpr *SS) {
519    SymbolSize = SS;
520  }
521
522  const MCExpr *getSize() const {
523    return SymbolSize;
524  }
525
526
527  /// getCommonAlignment - Return the alignment of a 'common' symbol.
528  unsigned getCommonAlignment() const {
529    assert(isCommon() && "Not a 'common' symbol!");
530    return CommonAlign;
531  }
532
533  /// getFlags - Get the (implementation defined) symbol flags.
534  uint32_t getFlags() const { return Flags; }
535
536  /// setFlags - Set the (implementation defined) symbol flags.
537  void setFlags(uint32_t Value) { Flags = Value; }
538
539  /// modifyFlags - Modify the flags via a mask
540  void modifyFlags(uint32_t Value, uint32_t Mask) {
541    Flags = (Flags & ~Mask) | Value;
542  }
543
544  /// getIndex - Get the (implementation defined) index.
545  uint64_t getIndex() const { return Index; }
546
547  /// setIndex - Set the (implementation defined) index.
548  void setIndex(uint64_t Value) { Index = Value; }
549
550  /// @}
551
552  void dump();
553};
554
555// FIXME: This really doesn't belong here. See comments below.
556struct IndirectSymbolData {
557  MCSymbol *Symbol;
558  MCSectionData *SectionData;
559};
560
561class MCAssembler {
562  friend class MCAsmLayout;
563
564public:
565  typedef iplist<MCSectionData> SectionDataListType;
566  typedef iplist<MCSymbolData> SymbolDataListType;
567
568  typedef SectionDataListType::const_iterator const_iterator;
569  typedef SectionDataListType::iterator iterator;
570
571  typedef SymbolDataListType::const_iterator const_symbol_iterator;
572  typedef SymbolDataListType::iterator symbol_iterator;
573
574  typedef std::vector<IndirectSymbolData>::const_iterator
575    const_indirect_symbol_iterator;
576  typedef std::vector<IndirectSymbolData>::iterator indirect_symbol_iterator;
577
578private:
579  MCAssembler(const MCAssembler&);    // DO NOT IMPLEMENT
580  void operator=(const MCAssembler&); // DO NOT IMPLEMENT
581
582  MCContext &Context;
583
584  TargetAsmBackend &Backend;
585
586  MCCodeEmitter &Emitter;
587
588  raw_ostream &OS;
589
590  iplist<MCSectionData> Sections;
591
592  iplist<MCSymbolData> Symbols;
593
594  /// The map of sections to their associated assembler backend data.
595  //
596  // FIXME: Avoid this indirection?
597  DenseMap<const MCSection*, MCSectionData*> SectionMap;
598
599  /// The map of symbols to their associated assembler backend data.
600  //
601  // FIXME: Avoid this indirection?
602  DenseMap<const MCSymbol*, MCSymbolData*> SymbolMap;
603
604  std::vector<IndirectSymbolData> IndirectSymbols;
605
606  unsigned RelaxAll : 1;
607  unsigned SubsectionsViaSymbols : 1;
608
609private:
610  /// Evaluate a fixup to a relocatable expression and the value which should be
611  /// placed into the fixup.
612  ///
613  /// \param Layout The layout to use for evaluation.
614  /// \param Fixup The fixup to evaluate.
615  /// \param DF The fragment the fixup is inside.
616  /// \param Target [out] On return, the relocatable expression the fixup
617  /// evaluates to.
618  /// \param Value [out] On return, the value of the fixup as currently layed
619  /// out.
620  /// \return Whether the fixup value was fully resolved. This is true if the
621  /// \arg Value result is fixed, otherwise the value may change due to
622  /// relocation.
623  bool EvaluateFixup(const MCAsmLayout &Layout,
624                     const MCFixup &Fixup, const MCFragment *DF,
625                     MCValue &Target, uint64_t &Value) const;
626
627  /// Check whether a fixup can be satisfied, or whether it needs to be relaxed
628  /// (increased in size, in order to hold its value correctly).
629  bool FixupNeedsRelaxation(const MCFixup &Fixup, const MCFragment *DF,
630                            const MCAsmLayout &Layout) const;
631
632  /// Check whether the given fragment needs relaxation.
633  bool FragmentNeedsRelaxation(const MCInstFragment *IF,
634                               const MCAsmLayout &Layout) const;
635
636  /// Compute the effective fragment size assuming it is layed out at the given
637  /// \arg SectionAddress and \arg FragmentOffset.
638  uint64_t ComputeFragmentSize(MCAsmLayout &Layout, const MCFragment &F,
639                               uint64_t SectionAddress,
640                               uint64_t FragmentOffset) const;
641
642  /// LayoutOnce - Perform one layout iteration and return true if any offsets
643  /// were adjusted.
644  bool LayoutOnce(MCAsmLayout &Layout);
645
646  /// FinishLayout - Finalize a layout, including fragment lowering.
647  void FinishLayout(MCAsmLayout &Layout);
648
649public:
650  /// Find the symbol which defines the atom containing the given symbol, or
651  /// null if there is no such symbol.
652  const MCSymbolData *getAtom(const MCAsmLayout &Layout,
653                              const MCSymbolData *Symbol) const;
654
655  /// Check whether a particular symbol is visible to the linker and is required
656  /// in the symbol table, or whether it can be discarded by the assembler. This
657  /// also effects whether the assembler treats the label as potentially
658  /// defining a separate atom.
659  bool isSymbolLinkerVisible(const MCSymbol &SD) const;
660
661  /// Emit the section contents using the given object writer.
662  //
663  // FIXME: Should MCAssembler always have a reference to the object writer?
664  void WriteSectionData(const MCSectionData *Section, const MCAsmLayout &Layout,
665                        MCObjectWriter *OW) const;
666
667  void AddSectionToTheEnd(MCSectionData &SD, MCAsmLayout &Layout);
668
669public:
670  /// Construct a new assembler instance.
671  ///
672  /// \arg OS - The stream to output to.
673  //
674  // FIXME: How are we going to parameterize this? Two obvious options are stay
675  // concrete and require clients to pass in a target like object. The other
676  // option is to make this abstract, and have targets provide concrete
677  // implementations as we do with AsmParser.
678  MCAssembler(MCContext &_Context, TargetAsmBackend &_Backend,
679              MCCodeEmitter &_Emitter, raw_ostream &OS);
680  ~MCAssembler();
681
682  MCContext &getContext() const { return Context; }
683
684  TargetAsmBackend &getBackend() const { return Backend; }
685
686  MCCodeEmitter &getEmitter() const { return Emitter; }
687
688  /// Finish - Do final processing and write the object to the output stream.
689  /// \arg Writer is used for custom object writer (as the MCJIT does),
690  /// if not specified it is automatically created from backend.
691  void Finish(MCObjectWriter *Writer = 0);
692
693  // FIXME: This does not belong here.
694  bool getSubsectionsViaSymbols() const {
695    return SubsectionsViaSymbols;
696  }
697  void setSubsectionsViaSymbols(bool Value) {
698    SubsectionsViaSymbols = Value;
699  }
700
701  bool getRelaxAll() const { return RelaxAll; }
702  void setRelaxAll(bool Value) { RelaxAll = Value; }
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