MC: Route access to SectionData offset and file size through MCAsmLayout.
[oota-llvm.git] / include / llvm / MC / MCAssembler.h
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
23 namespace llvm {
24 class raw_ostream;
25 class MCAsmLayout;
26 class MCAssembler;
27 class MCContext;
28 class MCCodeEmitter;
29 class MCExpr;
30 class MCFragment;
31 class MCObjectWriter;
32 class MCSection;
33 class MCSectionData;
34 class MCSymbol;
35 class MCValue;
36 class 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.
43 class MCAsmFixup {
44 public:
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
54 public:
55   MCAsmFixup(uint64_t _Offset, const MCExpr &_Value, MCFixupKind _Kind)
56     : Offset(_Offset), Value(&_Value), Kind(_Kind) {}
57 };
58
59 class 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
65 public:
66   enum FragmentType {
67     FT_Align,
68     FT_Data,
69     FT_Fill,
70     FT_Inst,
71     FT_Org,
72     FT_ZeroFill
73   };
74
75 private:
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
96 protected:
97   MCFragment(FragmentType _Kind, MCSectionData *_Parent = 0);
98
99 public:
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
114 class MCDataFragment : public MCFragment {
115   SmallString<32> Contents;
116
117   /// Fixups - The list of fixups in this fragment.
118   std::vector<MCAsmFixup> Fixups;
119
120 public:
121   typedef std::vector<MCAsmFixup>::const_iterator const_fixup_iterator;
122   typedef std::vector<MCAsmFixup>::iterator fixup_iterator;
123
124 public:
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.
170 class 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
180 public:
181   typedef SmallVectorImpl<MCAsmFixup>::const_iterator const_fixup_iterator;
182   typedef SmallVectorImpl<MCAsmFixup>::iterator fixup_iterator;
183
184 public:
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
227 class 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
245 public:
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
276 class 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
286 public:
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
311 class 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
318 public:
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.
342 class 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
349 public:
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.
374 class 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
380 public:
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
389 private:
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
418 public:
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.
457 class MCSymbolData : public ilist_node<MCSymbolData> {
458 public:
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
493 public:
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.
562 struct IndirectSymbolData {
563   MCSymbol *Symbol;
564   MCSectionData *SectionData;
565 };
566
567 class MCAssembler {
568 public:
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
582 private:
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
612 private:
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
651 public:
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
679 public:
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