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