MC: Route access to Fragment offset and effective 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   /// @name Fragment Access
429   /// @{
430
431   const FragmentListType &getFragmentList() const { return Fragments; }
432   FragmentListType &getFragmentList() { return Fragments; }
433
434   iterator begin() { return Fragments.begin(); }
435   const_iterator begin() const { return Fragments.begin(); }
436
437   iterator end() { return Fragments.end(); }
438   const_iterator end() const { return Fragments.end(); }
439
440   reverse_iterator rbegin() { return Fragments.rbegin(); }
441   const_reverse_iterator rbegin() const { return Fragments.rbegin(); }
442
443   reverse_iterator rend() { return Fragments.rend(); }
444   const_reverse_iterator rend() const { return Fragments.rend(); }
445
446   size_t size() const { return Fragments.size(); }
447
448   bool empty() const { return Fragments.empty(); }
449
450   /// @}
451   /// @name Assembler Backend Support
452   /// @{
453   //
454   // FIXME: This could all be kept private to the assembler implementation.
455
456   uint64_t getSize() const {
457     assert(Size != ~UINT64_C(0) && "File size not set!");
458     return Size;
459   }
460   void setSize(uint64_t Value) { Size = Value; }
461
462   uint64_t getFileSize() const {
463     assert(FileSize != ~UINT64_C(0) && "File size not set!");
464     return FileSize;
465   }
466   void setFileSize(uint64_t Value) { FileSize = Value; }
467
468   bool hasInstructions() const { return HasInstructions; }
469   void setHasInstructions(bool Value) { HasInstructions = Value; }
470
471   /// @}
472
473   void dump();
474 };
475
476 // FIXME: Same concerns as with SectionData.
477 class MCSymbolData : public ilist_node<MCSymbolData> {
478 public:
479   const MCSymbol *Symbol;
480
481   /// Fragment - The fragment this symbol's value is relative to, if any.
482   MCFragment *Fragment;
483
484   /// Offset - The offset to apply to the fragment address to form this symbol's
485   /// value.
486   uint64_t Offset;
487
488   /// IsExternal - True if this symbol is visible outside this translation
489   /// unit.
490   unsigned IsExternal : 1;
491
492   /// IsPrivateExtern - True if this symbol is private extern.
493   unsigned IsPrivateExtern : 1;
494
495   /// CommonSize - The size of the symbol, if it is 'common', or 0.
496   //
497   // FIXME: Pack this in with other fields? We could put it in offset, since a
498   // common symbol can never get a definition.
499   uint64_t CommonSize;
500
501   /// CommonAlign - The alignment of the symbol, if it is 'common'.
502   //
503   // FIXME: Pack this in with other fields?
504   unsigned CommonAlign;
505
506   /// Flags - The Flags field is used by object file implementations to store
507   /// additional per symbol information which is not easily classified.
508   uint32_t Flags;
509
510   /// Index - Index field, for use by the object file implementation.
511   uint64_t Index;
512
513 public:
514   // Only for use as sentinel.
515   MCSymbolData();
516   MCSymbolData(const MCSymbol &_Symbol, MCFragment *_Fragment, uint64_t _Offset,
517                MCAssembler *A = 0);
518
519   /// @name Accessors
520   /// @{
521
522   const MCSymbol &getSymbol() const { return *Symbol; }
523
524   MCFragment *getFragment() const { return Fragment; }
525   void setFragment(MCFragment *Value) { Fragment = Value; }
526
527   uint64_t getOffset() const { return Offset; }
528   void setOffset(uint64_t Value) { Offset = Value; }
529
530   /// @}
531   /// @name Symbol Attributes
532   /// @{
533
534   bool isExternal() const { return IsExternal; }
535   void setExternal(bool Value) { IsExternal = Value; }
536
537   bool isPrivateExtern() const { return IsPrivateExtern; }
538   void setPrivateExtern(bool Value) { IsPrivateExtern = Value; }
539
540   /// isCommon - Is this a 'common' symbol.
541   bool isCommon() const { return CommonSize != 0; }
542
543   /// setCommon - Mark this symbol as being 'common'.
544   ///
545   /// \param Size - The size of the symbol.
546   /// \param Align - The alignment of the symbol.
547   void setCommon(uint64_t Size, unsigned Align) {
548     CommonSize = Size;
549     CommonAlign = Align;
550   }
551
552   /// getCommonSize - Return the size of a 'common' symbol.
553   uint64_t getCommonSize() const {
554     assert(isCommon() && "Not a 'common' symbol!");
555     return CommonSize;
556   }
557
558   /// getCommonAlignment - Return the alignment of a 'common' symbol.
559   unsigned getCommonAlignment() const {
560     assert(isCommon() && "Not a 'common' symbol!");
561     return CommonAlign;
562   }
563
564   /// getFlags - Get the (implementation defined) symbol flags.
565   uint32_t getFlags() const { return Flags; }
566
567   /// setFlags - Set the (implementation defined) symbol flags.
568   void setFlags(uint32_t Value) { Flags = Value; }
569
570   /// getIndex - Get the (implementation defined) index.
571   uint64_t getIndex() const { return Index; }
572
573   /// setIndex - Set the (implementation defined) index.
574   void setIndex(uint64_t Value) { Index = Value; }
575
576   /// @}
577
578   void dump();
579 };
580
581 // FIXME: This really doesn't belong here. See comments below.
582 struct IndirectSymbolData {
583   MCSymbol *Symbol;
584   MCSectionData *SectionData;
585 };
586
587 class MCAssembler {
588 public:
589   typedef iplist<MCSectionData> SectionDataListType;
590   typedef iplist<MCSymbolData> SymbolDataListType;
591
592   typedef SectionDataListType::const_iterator const_iterator;
593   typedef SectionDataListType::iterator iterator;
594
595   typedef SymbolDataListType::const_iterator const_symbol_iterator;
596   typedef SymbolDataListType::iterator symbol_iterator;
597
598   typedef std::vector<IndirectSymbolData>::const_iterator
599     const_indirect_symbol_iterator;
600   typedef std::vector<IndirectSymbolData>::iterator indirect_symbol_iterator;
601
602 private:
603   MCAssembler(const MCAssembler&);    // DO NOT IMPLEMENT
604   void operator=(const MCAssembler&); // DO NOT IMPLEMENT
605
606   MCContext &Context;
607
608   TargetAsmBackend &Backend;
609
610   MCCodeEmitter &Emitter;
611
612   raw_ostream &OS;
613
614   iplist<MCSectionData> Sections;
615
616   iplist<MCSymbolData> Symbols;
617
618   /// The map of sections to their associated assembler backend data.
619   //
620   // FIXME: Avoid this indirection?
621   DenseMap<const MCSection*, MCSectionData*> SectionMap;
622
623   /// The map of symbols to their associated assembler backend data.
624   //
625   // FIXME: Avoid this indirection?
626   DenseMap<const MCSymbol*, MCSymbolData*> SymbolMap;
627
628   std::vector<IndirectSymbolData> IndirectSymbols;
629
630   unsigned SubsectionsViaSymbols : 1;
631
632 private:
633   /// Evaluate a fixup to a relocatable expression and the value which should be
634   /// placed into the fixup.
635   ///
636   /// \param Layout The layout to use for evaluation.
637   /// \param Fixup The fixup to evaluate.
638   /// \param DF The fragment the fixup is inside.
639   /// \param Target [out] On return, the relocatable expression the fixup
640   /// evaluates to.
641   /// \param Value [out] On return, the value of the fixup as currently layed
642   /// out.
643   /// \return Whether the fixup value was fully resolved. This is true if the
644   /// \arg Value result is fixed, otherwise the value may change due to
645   /// relocation.
646   bool EvaluateFixup(const MCAsmLayout &Layout,
647                      const MCAsmFixup &Fixup, const MCFragment *DF,
648                      MCValue &Target, uint64_t &Value) const;
649
650   /// Check whether a fixup can be satisfied, or whether it needs to be relaxed
651   /// (increased in size, in order to hold its value correctly).
652   bool FixupNeedsRelaxation(const MCAsmFixup &Fixup, const MCFragment *DF,
653                             const MCAsmLayout &Layout) const;
654
655   /// Check whether the given fragment needs relaxation.
656   bool FragmentNeedsRelaxation(const MCInstFragment *IF,
657                                const MCAsmLayout &Layout) const;
658
659   /// LayoutSection - Assign offsets and sizes to the fragments in the section
660   /// \arg SD, and update the section size. The section file offset should
661   /// already have been computed.
662   void LayoutSection(MCSectionData &SD, MCAsmLayout &Layout);
663
664   /// LayoutOnce - Perform one layout iteration and return true if any offsets
665   /// were adjusted.
666   bool LayoutOnce(MCAsmLayout &Layout);
667
668   /// FinishLayout - Finalize a layout, including fragment lowering.
669   void FinishLayout(MCAsmLayout &Layout);
670
671 public:
672   /// Find the symbol which defines the atom containing given address, inside
673   /// the given section, or null if there is no such symbol.
674   //
675   // FIXME-PERF: Eliminate this, it is very slow.
676   const MCSymbolData *getAtomForAddress(const MCAsmLayout &Layout,
677                                         const MCSectionData *Section,
678                                         uint64_t Address) const;
679
680   /// Find the symbol which defines the atom containing the given symbol, or
681   /// null if there is no such symbol.
682   //
683   // FIXME-PERF: Eliminate this, it is very slow.
684   const MCSymbolData *getAtom(const MCAsmLayout &Layout,
685                               const MCSymbolData *Symbol) const;
686
687   /// Check whether a particular symbol is visible to the linker and is required
688   /// in the symbol table, or whether it can be discarded by the assembler. This
689   /// also effects whether the assembler treats the label as potentially
690   /// defining a separate atom.
691   bool isSymbolLinkerVisible(const MCSymbolData *SD) const;
692
693   /// Emit the section contents using the given object writer.
694   //
695   // FIXME: Should MCAssembler always have a reference to the object writer?
696   void WriteSectionData(const MCSectionData *Section, const MCAsmLayout &Layout,
697                         MCObjectWriter *OW) const;
698
699 public:
700   /// Construct a new assembler instance.
701   ///
702   /// \arg OS - The stream to output to.
703   //
704   // FIXME: How are we going to parameterize this? Two obvious options are stay
705   // concrete and require clients to pass in a target like object. The other
706   // option is to make this abstract, and have targets provide concrete
707   // implementations as we do with AsmParser.
708   MCAssembler(MCContext &_Context, TargetAsmBackend &_Backend,
709               MCCodeEmitter &_Emitter, raw_ostream &OS);
710   ~MCAssembler();
711
712   MCContext &getContext() const { return Context; }
713
714   TargetAsmBackend &getBackend() const { return Backend; }
715
716   MCCodeEmitter &getEmitter() const { return Emitter; }
717
718   /// Finish - Do final processing and write the object to the output stream.
719   void Finish();
720
721   // FIXME: This does not belong here.
722   bool getSubsectionsViaSymbols() const {
723     return SubsectionsViaSymbols;
724   }
725   void setSubsectionsViaSymbols(bool Value) {
726     SubsectionsViaSymbols = Value;
727   }
728
729   /// @name Section List Access
730   /// @{
731
732   const SectionDataListType &getSectionList() const { return Sections; }
733   SectionDataListType &getSectionList() { return Sections; }
734
735   iterator begin() { return Sections.begin(); }
736   const_iterator begin() const { return Sections.begin(); }
737
738   iterator end() { return Sections.end(); }
739   const_iterator end() const { return Sections.end(); }
740
741   size_t size() const { return Sections.size(); }
742
743   /// @}
744   /// @name Symbol List Access
745   /// @{
746
747   const SymbolDataListType &getSymbolList() const { return Symbols; }
748   SymbolDataListType &getSymbolList() { return Symbols; }
749
750   symbol_iterator symbol_begin() { return Symbols.begin(); }
751   const_symbol_iterator symbol_begin() const { return Symbols.begin(); }
752
753   symbol_iterator symbol_end() { return Symbols.end(); }
754   const_symbol_iterator symbol_end() const { return Symbols.end(); }
755
756   size_t symbol_size() const { return Symbols.size(); }
757
758   /// @}
759   /// @name Indirect Symbol List Access
760   /// @{
761
762   // FIXME: This is a total hack, this should not be here. Once things are
763   // factored so that the streamer has direct access to the .o writer, it can
764   // disappear.
765   std::vector<IndirectSymbolData> &getIndirectSymbols() {
766     return IndirectSymbols;
767   }
768
769   indirect_symbol_iterator indirect_symbol_begin() {
770     return IndirectSymbols.begin();
771   }
772   const_indirect_symbol_iterator indirect_symbol_begin() const {
773     return IndirectSymbols.begin();
774   }
775
776   indirect_symbol_iterator indirect_symbol_end() {
777     return IndirectSymbols.end();
778   }
779   const_indirect_symbol_iterator indirect_symbol_end() const {
780     return IndirectSymbols.end();
781   }
782
783   size_t indirect_symbol_size() const { return IndirectSymbols.size(); }
784
785   /// @}
786   /// @name Backend Data Access
787   /// @{
788
789   MCSectionData &getSectionData(const MCSection &Section) const {
790     MCSectionData *Entry = SectionMap.lookup(&Section);
791     assert(Entry && "Missing section data!");
792     return *Entry;
793   }
794
795   MCSectionData &getOrCreateSectionData(const MCSection &Section,
796                                         bool *Created = 0) {
797     MCSectionData *&Entry = SectionMap[&Section];
798
799     if (Created) *Created = !Entry;
800     if (!Entry)
801       Entry = new MCSectionData(Section, this);
802
803     return *Entry;
804   }
805
806   MCSymbolData &getSymbolData(const MCSymbol &Symbol) const {
807     MCSymbolData *Entry = SymbolMap.lookup(&Symbol);
808     assert(Entry && "Missing symbol data!");
809     return *Entry;
810   }
811
812   MCSymbolData &getOrCreateSymbolData(const MCSymbol &Symbol,
813                                       bool *Created = 0) {
814     MCSymbolData *&Entry = SymbolMap[&Symbol];
815
816     if (Created) *Created = !Entry;
817     if (!Entry)
818       Entry = new MCSymbolData(Symbol, 0, 0, this);
819
820     return *Entry;
821   }
822
823   /// @}
824
825   void dump();
826 };
827
828 } // end namespace llvm
829
830 #endif