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