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