MCAssembler.h revision 432cd5fd9b4c97f1e4a53fcf45e16f7dd6bc085e
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  /// @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.
477class MCSymbolData : public ilist_node<MCSymbolData> {
478public:
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
513public:
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.
582struct IndirectSymbolData {
583  MCSymbol *Symbol;
584  MCSectionData *SectionData;
585};
586
587class MCAssembler {
588public:
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
602private:
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
632private:
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
671public:
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
699public:
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
831