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