OSDN Git Service

Refactor MCInstFragment and MCDataFragment to adhere to a common interface,
[android-x86/external-llvm.git] / include / llvm / MC / MCAssembler.h
1 //===- MCAssembler.h - Object File Generation -------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #ifndef LLVM_MC_MCASSEMBLER_H
11 #define LLVM_MC_MCASSEMBLER_H
12
13 #include "llvm/ADT/DenseMap.h"
14 #include "llvm/ADT/SmallPtrSet.h"
15 #include "llvm/ADT/SmallString.h"
16 #include "llvm/ADT/ilist.h"
17 #include "llvm/ADT/ilist_node.h"
18 #include "llvm/MC/MCFixup.h"
19 #include "llvm/MC/MCInst.h"
20 #include "llvm/Support/Casting.h"
21 #include "llvm/Support/DataTypes.h"
22 #include <vector> // FIXME: Shouldn't be needed.
23
24 namespace llvm {
25 class raw_ostream;
26 class MCAsmLayout;
27 class MCAssembler;
28 class MCContext;
29 class MCCodeEmitter;
30 class MCExpr;
31 class MCFragment;
32 class MCObjectWriter;
33 class MCSection;
34 class MCSectionData;
35 class MCSymbol;
36 class MCSymbolData;
37 class MCValue;
38 class MCAsmBackend;
39
40 class MCFragment : public ilist_node<MCFragment> {
41   friend class MCAsmLayout;
42
43   MCFragment(const MCFragment&) LLVM_DELETED_FUNCTION;
44   void operator=(const MCFragment&) LLVM_DELETED_FUNCTION;
45
46 public:
47   enum FragmentType {
48     FT_Align,
49     FT_Data,
50     FT_Fill,
51     FT_Inst,
52     FT_Org,
53     FT_Dwarf,
54     FT_DwarfFrame,
55     FT_LEB
56   };
57
58 private:
59   FragmentType Kind;
60
61   /// Parent - The data for the section this fragment is in.
62   MCSectionData *Parent;
63
64   /// Atom - The atom this fragment is in, as represented by it's defining
65   /// symbol. Atom's are only used by backends which set
66   /// \see MCAsmBackend::hasReliableSymbolDifference().
67   MCSymbolData *Atom;
68
69   /// @name Assembler Backend Data
70   /// @{
71   //
72   // FIXME: This could all be kept private to the assembler implementation.
73
74   /// Offset - The offset of this fragment in its section. This is ~0 until
75   /// initialized.
76   uint64_t Offset;
77
78   /// LayoutOrder - The layout order of this fragment.
79   unsigned LayoutOrder;
80
81   /// @}
82
83 protected:
84   MCFragment(FragmentType _Kind, MCSectionData *_Parent = 0);
85
86 public:
87   // Only for sentinel.
88   MCFragment();
89   virtual ~MCFragment();
90
91   FragmentType getKind() const { return Kind; }
92
93   MCSectionData *getParent() const { return Parent; }
94   void setParent(MCSectionData *Value) { Parent = Value; }
95
96   MCSymbolData *getAtom() const { return Atom; }
97   void setAtom(MCSymbolData *Value) { Atom = Value; }
98
99   unsigned getLayoutOrder() const { return LayoutOrder; }
100   void setLayoutOrder(unsigned Value) { LayoutOrder = Value; }
101
102   void dump();
103 };
104
105 class MCEncodedFragment : public MCFragment {
106   virtual void anchor();
107 public:
108   MCEncodedFragment(MCFragment::FragmentType FType, MCSectionData *SD = 0)
109     : MCFragment(FType, SD) {
110   }
111   virtual ~MCEncodedFragment();
112
113   typedef SmallVectorImpl<MCFixup>::const_iterator const_fixup_iterator;
114   typedef SmallVectorImpl<MCFixup>::iterator fixup_iterator;
115
116   virtual SmallString<32> &getContents() = 0;
117   virtual const SmallString<32> &getContents() const = 0;
118
119   virtual SmallVectorImpl<MCFixup> &getFixups() = 0;
120   virtual const SmallVectorImpl<MCFixup> &getFixups() const = 0;
121
122   virtual fixup_iterator fixup_begin() = 0;
123   virtual const_fixup_iterator fixup_begin() const  = 0;
124   virtual fixup_iterator fixup_end() = 0;
125   virtual const_fixup_iterator fixup_end() const = 0;
126
127   static bool classof(const MCFragment *F) {
128     MCFragment::FragmentType Kind = F->getKind();
129     return Kind == MCFragment::FT_Inst || Kind == MCFragment::FT_Data;
130   }
131 };
132
133 class MCDataFragment : public MCEncodedFragment {
134   virtual void anchor();
135   SmallString<32> Contents;
136
137   /// Fixups - The list of fixups in this fragment.
138   SmallVector<MCFixup, 4> Fixups;
139
140 public:
141   MCDataFragment(MCSectionData *SD = 0)
142     : MCEncodedFragment(FT_Data, SD) {
143   }
144
145   SmallString<32> &getContents() { return Contents; }
146   const SmallString<32> &getContents() const { return Contents; }
147
148   SmallVectorImpl<MCFixup> &getFixups() {
149     return Fixups;
150   }
151
152   const SmallVectorImpl<MCFixup> &getFixups() const {
153     return Fixups;
154   }
155
156   fixup_iterator fixup_begin() { return Fixups.begin(); }
157   const_fixup_iterator fixup_begin() const { return Fixups.begin(); }
158
159   fixup_iterator fixup_end() {return Fixups.end();}
160   const_fixup_iterator fixup_end() const {return Fixups.end();}
161
162   static bool classof(const MCFragment *F) {
163     return F->getKind() == MCFragment::FT_Data;
164   }
165 };
166
167 class MCInstFragment : public MCEncodedFragment {
168   virtual void anchor();
169
170   /// Inst - The instruction this is a fragment for.
171   MCInst Inst;
172
173   /// Contents - Binary data for the currently encoded instruction.
174   SmallString<32> Contents;
175
176   /// Fixups - The list of fixups in this fragment.
177   SmallVector<MCFixup, 1> Fixups;
178
179 public:
180   MCInstFragment(const MCInst &_Inst, MCSectionData *SD = 0)
181     : MCEncodedFragment(FT_Inst, SD), Inst(_Inst) {
182   }
183
184   SmallString<32> &getContents() { return Contents; }
185   const SmallString<32> &getContents() const { return Contents; }
186
187   unsigned getInstSize() const { return Contents.size(); }
188   const MCInst &getInst() const { return Inst; }
189   void setInst(const MCInst& Value) { Inst = Value; }
190
191   SmallVectorImpl<MCFixup> &getFixups() {
192     return Fixups;
193   }
194
195   const SmallVectorImpl<MCFixup> &getFixups() const {
196     return Fixups;
197   }
198
199   fixup_iterator fixup_begin() { return Fixups.begin(); }
200   const_fixup_iterator fixup_begin() const { return Fixups.begin(); }
201
202   fixup_iterator fixup_end() {return Fixups.end();}
203   const_fixup_iterator fixup_end() const {return Fixups.end();}
204
205   static bool classof(const MCFragment *F) {
206     return F->getKind() == MCFragment::FT_Inst;
207   }
208 };
209
210 class MCAlignFragment : public MCFragment {
211   virtual void anchor();
212
213   /// Alignment - The alignment to ensure, in bytes.
214   unsigned Alignment;
215
216   /// Value - Value to use for filling padding bytes.
217   int64_t Value;
218
219   /// ValueSize - The size of the integer (in bytes) of \p Value.
220   unsigned ValueSize;
221
222   /// MaxBytesToEmit - The maximum number of bytes to emit; if the alignment
223   /// cannot be satisfied in this width then this fragment is ignored.
224   unsigned MaxBytesToEmit;
225
226   /// EmitNops - Flag to indicate that (optimal) NOPs should be emitted instead
227   /// of using the provided value. The exact interpretation of this flag is
228   /// target dependent.
229   bool EmitNops : 1;
230
231 public:
232   MCAlignFragment(unsigned _Alignment, int64_t _Value, unsigned _ValueSize,
233                   unsigned _MaxBytesToEmit, MCSectionData *SD = 0)
234     : MCFragment(FT_Align, SD), Alignment(_Alignment),
235       Value(_Value),ValueSize(_ValueSize),
236       MaxBytesToEmit(_MaxBytesToEmit), EmitNops(false) {}
237
238   /// @name Accessors
239   /// @{
240
241   unsigned getAlignment() const { return Alignment; }
242
243   int64_t getValue() const { return Value; }
244
245   unsigned getValueSize() const { return ValueSize; }
246
247   unsigned getMaxBytesToEmit() const { return MaxBytesToEmit; }
248
249   bool hasEmitNops() const { return EmitNops; }
250   void setEmitNops(bool Value) { EmitNops = Value; }
251
252   /// @}
253
254   static bool classof(const MCFragment *F) {
255     return F->getKind() == MCFragment::FT_Align;
256   }
257 };
258
259 class MCFillFragment : public MCFragment {
260   virtual void anchor();
261
262   /// Value - Value to use for filling bytes.
263   int64_t Value;
264
265   /// ValueSize - The size (in bytes) of \p Value to use when filling, or 0 if
266   /// this is a virtual fill fragment.
267   unsigned ValueSize;
268
269   /// Size - The number of bytes to insert.
270   uint64_t Size;
271
272 public:
273   MCFillFragment(int64_t _Value, unsigned _ValueSize, uint64_t _Size,
274                  MCSectionData *SD = 0)
275     : MCFragment(FT_Fill, SD),
276       Value(_Value), ValueSize(_ValueSize), Size(_Size) {
277     assert((!ValueSize || (Size % ValueSize) == 0) &&
278            "Fill size must be a multiple of the value size!");
279   }
280
281   /// @name Accessors
282   /// @{
283
284   int64_t getValue() const { return Value; }
285
286   unsigned getValueSize() const { return ValueSize; }
287
288   uint64_t getSize() const { return Size; }
289
290   /// @}
291
292   static bool classof(const MCFragment *F) {
293     return F->getKind() == MCFragment::FT_Fill;
294   }
295 };
296
297 class MCOrgFragment : public MCFragment {
298   virtual void anchor();
299
300   /// Offset - The offset this fragment should start at.
301   const MCExpr *Offset;
302
303   /// Value - Value to use for filling bytes.
304   int8_t Value;
305
306 public:
307   MCOrgFragment(const MCExpr &_Offset, int8_t _Value, MCSectionData *SD = 0)
308     : MCFragment(FT_Org, SD),
309       Offset(&_Offset), Value(_Value) {}
310
311   /// @name Accessors
312   /// @{
313
314   const MCExpr &getOffset() const { return *Offset; }
315
316   uint8_t getValue() const { return Value; }
317
318   /// @}
319
320   static bool classof(const MCFragment *F) {
321     return F->getKind() == MCFragment::FT_Org;
322   }
323 };
324
325 class MCLEBFragment : public MCFragment {
326   virtual void anchor();
327
328   /// Value - The value this fragment should contain.
329   const MCExpr *Value;
330
331   /// IsSigned - True if this is a sleb128, false if uleb128.
332   bool IsSigned;
333
334   SmallString<8> Contents;
335 public:
336   MCLEBFragment(const MCExpr &Value_, bool IsSigned_, MCSectionData *SD)
337     : MCFragment(FT_LEB, SD),
338       Value(&Value_), IsSigned(IsSigned_) { Contents.push_back(0); }
339
340   /// @name Accessors
341   /// @{
342
343   const MCExpr &getValue() const { return *Value; }
344
345   bool isSigned() const { return IsSigned; }
346
347   SmallString<8> &getContents() { return Contents; }
348   const SmallString<8> &getContents() const { return Contents; }
349
350   /// @}
351
352   static bool classof(const MCFragment *F) {
353     return F->getKind() == MCFragment::FT_LEB;
354   }
355 };
356
357 class MCDwarfLineAddrFragment : public MCFragment {
358   virtual void anchor();
359
360   /// LineDelta - the value of the difference between the two line numbers
361   /// between two .loc dwarf directives.
362   int64_t LineDelta;
363
364   /// AddrDelta - The expression for the difference of the two symbols that
365   /// make up the address delta between two .loc dwarf directives.
366   const MCExpr *AddrDelta;
367
368   SmallString<8> Contents;
369
370 public:
371   MCDwarfLineAddrFragment(int64_t _LineDelta, const MCExpr &_AddrDelta,
372                       MCSectionData *SD)
373     : MCFragment(FT_Dwarf, SD),
374       LineDelta(_LineDelta), AddrDelta(&_AddrDelta) { Contents.push_back(0); }
375
376   /// @name Accessors
377   /// @{
378
379   int64_t getLineDelta() const { return LineDelta; }
380
381   const MCExpr &getAddrDelta() const { return *AddrDelta; }
382
383   SmallString<8> &getContents() { return Contents; }
384   const SmallString<8> &getContents() const { return Contents; }
385
386   /// @}
387
388   static bool classof(const MCFragment *F) {
389     return F->getKind() == MCFragment::FT_Dwarf;
390   }
391 };
392
393 class MCDwarfCallFrameFragment : public MCFragment {
394   virtual void anchor();
395
396   /// AddrDelta - The expression for the difference of the two symbols that
397   /// make up the address delta between two .cfi_* dwarf directives.
398   const MCExpr *AddrDelta;
399
400   SmallString<8> Contents;
401
402 public:
403   MCDwarfCallFrameFragment(const MCExpr &_AddrDelta,  MCSectionData *SD)
404     : MCFragment(FT_DwarfFrame, SD),
405       AddrDelta(&_AddrDelta) { Contents.push_back(0); }
406
407   /// @name Accessors
408   /// @{
409
410   const MCExpr &getAddrDelta() const { return *AddrDelta; }
411
412   SmallString<8> &getContents() { return Contents; }
413   const SmallString<8> &getContents() const { return Contents; }
414
415   /// @}
416
417   static bool classof(const MCFragment *F) {
418     return F->getKind() == MCFragment::FT_DwarfFrame;
419   }
420 };
421
422 // FIXME: Should this be a separate class, or just merged into MCSection? Since
423 // we anticipate the fast path being through an MCAssembler, the only reason to
424 // keep it out is for API abstraction.
425 class MCSectionData : public ilist_node<MCSectionData> {
426   friend class MCAsmLayout;
427
428   MCSectionData(const MCSectionData&) LLVM_DELETED_FUNCTION;
429   void operator=(const MCSectionData&) LLVM_DELETED_FUNCTION;
430
431 public:
432   typedef iplist<MCFragment> FragmentListType;
433
434   typedef FragmentListType::const_iterator const_iterator;
435   typedef FragmentListType::iterator iterator;
436
437   typedef FragmentListType::const_reverse_iterator const_reverse_iterator;
438   typedef FragmentListType::reverse_iterator reverse_iterator;
439
440 private:
441   FragmentListType Fragments;
442   const MCSection *Section;
443
444   /// Ordinal - The section index in the assemblers section list.
445   unsigned Ordinal;
446
447   /// LayoutOrder - The index of this section in the layout order.
448   unsigned LayoutOrder;
449
450   /// Alignment - The maximum alignment seen in this section.
451   unsigned Alignment;
452
453   /// @name Assembler Backend Data
454   /// @{
455   //
456   // FIXME: This could all be kept private to the assembler implementation.
457
458   /// HasInstructions - Whether this section has had instructions emitted into
459   /// it.
460   unsigned HasInstructions : 1;
461
462   /// @}
463
464 public:
465   // Only for use as sentinel.
466   MCSectionData();
467   MCSectionData(const MCSection &Section, MCAssembler *A = 0);
468
469   const MCSection &getSection() const { return *Section; }
470
471   unsigned getAlignment() const { return Alignment; }
472   void setAlignment(unsigned Value) { Alignment = Value; }
473
474   bool hasInstructions() const { return HasInstructions; }
475   void setHasInstructions(bool Value) { HasInstructions = Value; }
476
477   unsigned getOrdinal() const { return Ordinal; }
478   void setOrdinal(unsigned Value) { Ordinal = Value; }
479
480   unsigned getLayoutOrder() const { return LayoutOrder; }
481   void setLayoutOrder(unsigned Value) { LayoutOrder = Value; }
482
483   /// @name Fragment Access
484   /// @{
485
486   const FragmentListType &getFragmentList() const { return Fragments; }
487   FragmentListType &getFragmentList() { return Fragments; }
488
489   iterator begin() { return Fragments.begin(); }
490   const_iterator begin() const { return Fragments.begin(); }
491
492   iterator end() { return Fragments.end(); }
493   const_iterator end() const { return Fragments.end(); }
494
495   reverse_iterator rbegin() { return Fragments.rbegin(); }
496   const_reverse_iterator rbegin() const { return Fragments.rbegin(); }
497
498   reverse_iterator rend() { return Fragments.rend(); }
499   const_reverse_iterator rend() const { return Fragments.rend(); }
500
501   size_t size() const { return Fragments.size(); }
502
503   bool empty() const { return Fragments.empty(); }
504
505   void dump();
506
507   /// @}
508 };
509
510 // FIXME: Same concerns as with SectionData.
511 class MCSymbolData : public ilist_node<MCSymbolData> {
512 public:
513   const MCSymbol *Symbol;
514
515   /// Fragment - The fragment this symbol's value is relative to, if any.
516   MCFragment *Fragment;
517
518   /// Offset - The offset to apply to the fragment address to form this symbol's
519   /// value.
520   uint64_t Offset;
521
522   /// IsExternal - True if this symbol is visible outside this translation
523   /// unit.
524   unsigned IsExternal : 1;
525
526   /// IsPrivateExtern - True if this symbol is private extern.
527   unsigned IsPrivateExtern : 1;
528
529   /// CommonSize - The size of the symbol, if it is 'common', or 0.
530   //
531   // FIXME: Pack this in with other fields? We could put it in offset, since a
532   // common symbol can never get a definition.
533   uint64_t CommonSize;
534
535   /// SymbolSize - An expression describing how to calculate the size of
536   /// a symbol. If a symbol has no size this field will be NULL.
537   const MCExpr *SymbolSize;
538
539   /// CommonAlign - The alignment of the symbol, if it is 'common'.
540   //
541   // FIXME: Pack this in with other fields?
542   unsigned CommonAlign;
543
544   /// Flags - The Flags field is used by object file implementations to store
545   /// additional per symbol information which is not easily classified.
546   uint32_t Flags;
547
548   /// Index - Index field, for use by the object file implementation.
549   uint64_t Index;
550
551 public:
552   // Only for use as sentinel.
553   MCSymbolData();
554   MCSymbolData(const MCSymbol &_Symbol, MCFragment *_Fragment, uint64_t _Offset,
555                MCAssembler *A = 0);
556
557   /// @name Accessors
558   /// @{
559
560   const MCSymbol &getSymbol() const { return *Symbol; }
561
562   MCFragment *getFragment() const { return Fragment; }
563   void setFragment(MCFragment *Value) { Fragment = Value; }
564
565   uint64_t getOffset() const { return Offset; }
566   void setOffset(uint64_t Value) { Offset = Value; }
567
568   /// @}
569   /// @name Symbol Attributes
570   /// @{
571
572   bool isExternal() const { return IsExternal; }
573   void setExternal(bool Value) { IsExternal = Value; }
574
575   bool isPrivateExtern() const { return IsPrivateExtern; }
576   void setPrivateExtern(bool Value) { IsPrivateExtern = Value; }
577
578   /// isCommon - Is this a 'common' symbol.
579   bool isCommon() const { return CommonSize != 0; }
580
581   /// setCommon - Mark this symbol as being 'common'.
582   ///
583   /// \param Size - The size of the symbol.
584   /// \param Align - The alignment of the symbol.
585   void setCommon(uint64_t Size, unsigned Align) {
586     CommonSize = Size;
587     CommonAlign = Align;
588   }
589
590   /// getCommonSize - Return the size of a 'common' symbol.
591   uint64_t getCommonSize() const {
592     assert(isCommon() && "Not a 'common' symbol!");
593     return CommonSize;
594   }
595
596   void setSize(const MCExpr *SS) {
597     SymbolSize = SS;
598   }
599
600   const MCExpr *getSize() const {
601     return SymbolSize;
602   }
603
604
605   /// getCommonAlignment - Return the alignment of a 'common' symbol.
606   unsigned getCommonAlignment() const {
607     assert(isCommon() && "Not a 'common' symbol!");
608     return CommonAlign;
609   }
610
611   /// getFlags - Get the (implementation defined) symbol flags.
612   uint32_t getFlags() const { return Flags; }
613
614   /// setFlags - Set the (implementation defined) symbol flags.
615   void setFlags(uint32_t Value) { Flags = Value; }
616
617   /// modifyFlags - Modify the flags via a mask
618   void modifyFlags(uint32_t Value, uint32_t Mask) {
619     Flags = (Flags & ~Mask) | Value;
620   }
621
622   /// getIndex - Get the (implementation defined) index.
623   uint64_t getIndex() const { return Index; }
624
625   /// setIndex - Set the (implementation defined) index.
626   void setIndex(uint64_t Value) { Index = Value; }
627
628   /// @}
629
630   void dump();
631 };
632
633 // FIXME: This really doesn't belong here. See comments below.
634 struct IndirectSymbolData {
635   MCSymbol *Symbol;
636   MCSectionData *SectionData;
637 };
638
639 // FIXME: Ditto this. Purely so the Streamer and the ObjectWriter can talk
640 // to one another.
641 struct DataRegionData {
642   // This enum should be kept in sync w/ the mach-o definition in
643   // llvm/Object/MachOFormat.h.
644   enum KindTy { Data = 1, JumpTable8, JumpTable16, JumpTable32 } Kind;
645   MCSymbol *Start;
646   MCSymbol *End;
647 };
648
649 class MCAssembler {
650   friend class MCAsmLayout;
651
652 public:
653   typedef iplist<MCSectionData> SectionDataListType;
654   typedef iplist<MCSymbolData> SymbolDataListType;
655
656   typedef SectionDataListType::const_iterator const_iterator;
657   typedef SectionDataListType::iterator iterator;
658
659   typedef SymbolDataListType::const_iterator const_symbol_iterator;
660   typedef SymbolDataListType::iterator symbol_iterator;
661
662   typedef std::vector<IndirectSymbolData>::const_iterator
663     const_indirect_symbol_iterator;
664   typedef std::vector<IndirectSymbolData>::iterator indirect_symbol_iterator;
665
666   typedef std::vector<DataRegionData>::const_iterator
667     const_data_region_iterator;
668   typedef std::vector<DataRegionData>::iterator data_region_iterator;
669
670 private:
671   MCAssembler(const MCAssembler&) LLVM_DELETED_FUNCTION;
672   void operator=(const MCAssembler&) LLVM_DELETED_FUNCTION;
673
674   MCContext &Context;
675
676   MCAsmBackend &Backend;
677
678   MCCodeEmitter &Emitter;
679
680   MCObjectWriter &Writer;
681
682   raw_ostream &OS;
683
684   iplist<MCSectionData> Sections;
685
686   iplist<MCSymbolData> Symbols;
687
688   /// The map of sections to their associated assembler backend data.
689   //
690   // FIXME: Avoid this indirection?
691   DenseMap<const MCSection*, MCSectionData*> SectionMap;
692
693   /// The map of symbols to their associated assembler backend data.
694   //
695   // FIXME: Avoid this indirection?
696   DenseMap<const MCSymbol*, MCSymbolData*> SymbolMap;
697
698   std::vector<IndirectSymbolData> IndirectSymbols;
699
700   std::vector<DataRegionData> DataRegions;
701   /// The set of function symbols for which a .thumb_func directive has
702   /// been seen.
703   //
704   // FIXME: We really would like this in target specific code rather than
705   // here. Maybe when the relocation stuff moves to target specific,
706   // this can go with it? The streamer would need some target specific
707   // refactoring too.
708   SmallPtrSet<const MCSymbol*, 64> ThumbFuncs;
709
710   unsigned RelaxAll : 1;
711   unsigned NoExecStack : 1;
712   unsigned SubsectionsViaSymbols : 1;
713
714 private:
715   /// Evaluate a fixup to a relocatable expression and the value which should be
716   /// placed into the fixup.
717   ///
718   /// \param Layout The layout to use for evaluation.
719   /// \param Fixup The fixup to evaluate.
720   /// \param DF The fragment the fixup is inside.
721   /// \param Target [out] On return, the relocatable expression the fixup
722   /// evaluates to.
723   /// \param Value [out] On return, the value of the fixup as currently laid
724   /// out.
725   /// \return Whether the fixup value was fully resolved. This is true if the
726   /// \p Value result is fixed, otherwise the value may change due to
727   /// relocation.
728   bool evaluateFixup(const MCAsmLayout &Layout,
729                      const MCFixup &Fixup, const MCFragment *DF,
730                      MCValue &Target, uint64_t &Value) const;
731
732   /// Check whether a fixup can be satisfied, or whether it needs to be relaxed
733   /// (increased in size, in order to hold its value correctly).
734   bool fixupNeedsRelaxation(const MCFixup &Fixup, const MCInstFragment *DF,
735                             const MCAsmLayout &Layout) const;
736
737   /// Check whether the given fragment needs relaxation.
738   bool fragmentNeedsRelaxation(const MCInstFragment *IF,
739                                const MCAsmLayout &Layout) const;
740
741   /// layoutOnce - Perform one layout iteration and return true if any offsets
742   /// were adjusted.
743   bool layoutOnce(MCAsmLayout &Layout);
744
745   bool layoutSectionOnce(MCAsmLayout &Layout, MCSectionData &SD);
746
747   bool relaxInstruction(MCAsmLayout &Layout, MCInstFragment &IF);
748
749   bool relaxLEB(MCAsmLayout &Layout, MCLEBFragment &IF);
750
751   bool relaxDwarfLineAddr(MCAsmLayout &Layout, MCDwarfLineAddrFragment &DF);
752   bool relaxDwarfCallFrameFragment(MCAsmLayout &Layout,
753                                    MCDwarfCallFrameFragment &DF);
754
755   /// finishLayout - Finalize a layout, including fragment lowering.
756   void finishLayout(MCAsmLayout &Layout);
757
758   uint64_t handleFixup(const MCAsmLayout &Layout,
759                        MCFragment &F, const MCFixup &Fixup);
760
761 public:
762   /// Compute the effective fragment size assuming it is laid out at the given
763   /// \p SectionAddress and \p FragmentOffset.
764   uint64_t computeFragmentSize(const MCAsmLayout &Layout,
765                                const MCFragment &F) const;
766
767   /// Find the symbol which defines the atom containing the given symbol, or
768   /// null if there is no such symbol.
769   const MCSymbolData *getAtom(const MCSymbolData *Symbol) const;
770
771   /// Check whether a particular symbol is visible to the linker and is required
772   /// in the symbol table, or whether it can be discarded by the assembler. This
773   /// also effects whether the assembler treats the label as potentially
774   /// defining a separate atom.
775   bool isSymbolLinkerVisible(const MCSymbol &SD) const;
776
777   /// Emit the section contents using the given object writer.
778   void writeSectionData(const MCSectionData *Section,
779                         const MCAsmLayout &Layout) const;
780
781   /// Check whether a given symbol has been flagged with .thumb_func.
782   bool isThumbFunc(const MCSymbol *Func) const {
783     return ThumbFuncs.count(Func);
784   }
785
786   /// Flag a function symbol as the target of a .thumb_func directive.
787   void setIsThumbFunc(const MCSymbol *Func) { ThumbFuncs.insert(Func); }
788
789 public:
790   /// Construct a new assembler instance.
791   ///
792   /// \param OS The stream to output to.
793   //
794   // FIXME: How are we going to parameterize this? Two obvious options are stay
795   // concrete and require clients to pass in a target like object. The other
796   // option is to make this abstract, and have targets provide concrete
797   // implementations as we do with AsmParser.
798   MCAssembler(MCContext &Context_, MCAsmBackend &Backend_,
799               MCCodeEmitter &Emitter_, MCObjectWriter &Writer_,
800               raw_ostream &OS);
801   ~MCAssembler();
802
803   MCContext &getContext() const { return Context; }
804
805   MCAsmBackend &getBackend() const { return Backend; }
806
807   MCCodeEmitter &getEmitter() const { return Emitter; }
808
809   MCObjectWriter &getWriter() const { return Writer; }
810
811   /// Finish - Do final processing and write the object to the output stream.
812   /// \p Writer is used for custom object writer (as the MCJIT does),
813   /// if not specified it is automatically created from backend.
814   void Finish();
815
816   // FIXME: This does not belong here.
817   bool getSubsectionsViaSymbols() const {
818     return SubsectionsViaSymbols;
819   }
820   void setSubsectionsViaSymbols(bool Value) {
821     SubsectionsViaSymbols = Value;
822   }
823
824   bool getRelaxAll() const { return RelaxAll; }
825   void setRelaxAll(bool Value) { RelaxAll = Value; }
826
827   bool getNoExecStack() const { return NoExecStack; }
828   void setNoExecStack(bool Value) { NoExecStack = Value; }
829
830   /// @name Section List Access
831   /// @{
832
833   const SectionDataListType &getSectionList() const { return Sections; }
834   SectionDataListType &getSectionList() { return Sections; }
835
836   iterator begin() { return Sections.begin(); }
837   const_iterator begin() const { return Sections.begin(); }
838
839   iterator end() { return Sections.end(); }
840   const_iterator end() const { return Sections.end(); }
841
842   size_t size() const { return Sections.size(); }
843
844   /// @}
845   /// @name Symbol List Access
846   /// @{
847
848   const SymbolDataListType &getSymbolList() const { return Symbols; }
849   SymbolDataListType &getSymbolList() { return Symbols; }
850
851   symbol_iterator symbol_begin() { return Symbols.begin(); }
852   const_symbol_iterator symbol_begin() const { return Symbols.begin(); }
853
854   symbol_iterator symbol_end() { return Symbols.end(); }
855   const_symbol_iterator symbol_end() const { return Symbols.end(); }
856
857   size_t symbol_size() const { return Symbols.size(); }
858
859   /// @}
860   /// @name Indirect Symbol List Access
861   /// @{
862
863   // FIXME: This is a total hack, this should not be here. Once things are
864   // factored so that the streamer has direct access to the .o writer, it can
865   // disappear.
866   std::vector<IndirectSymbolData> &getIndirectSymbols() {
867     return IndirectSymbols;
868   }
869
870   indirect_symbol_iterator indirect_symbol_begin() {
871     return IndirectSymbols.begin();
872   }
873   const_indirect_symbol_iterator indirect_symbol_begin() const {
874     return IndirectSymbols.begin();
875   }
876
877   indirect_symbol_iterator indirect_symbol_end() {
878     return IndirectSymbols.end();
879   }
880   const_indirect_symbol_iterator indirect_symbol_end() const {
881     return IndirectSymbols.end();
882   }
883
884   size_t indirect_symbol_size() const { return IndirectSymbols.size(); }
885
886   /// @}
887   /// @name Data Region List Access
888   /// @{
889
890   // FIXME: This is a total hack, this should not be here. Once things are
891   // factored so that the streamer has direct access to the .o writer, it can
892   // disappear.
893   std::vector<DataRegionData> &getDataRegions() {
894     return DataRegions;
895   }
896
897   data_region_iterator data_region_begin() {
898     return DataRegions.begin();
899   }
900   const_data_region_iterator data_region_begin() const {
901     return DataRegions.begin();
902   }
903
904   data_region_iterator data_region_end() {
905     return DataRegions.end();
906   }
907   const_data_region_iterator data_region_end() const {
908     return DataRegions.end();
909   }
910
911   size_t data_region_size() const { return DataRegions.size(); }
912
913   /// @}
914   /// @name Backend Data Access
915   /// @{
916
917   MCSectionData &getSectionData(const MCSection &Section) const {
918     MCSectionData *Entry = SectionMap.lookup(&Section);
919     assert(Entry && "Missing section data!");
920     return *Entry;
921   }
922
923   MCSectionData &getOrCreateSectionData(const MCSection &Section,
924                                         bool *Created = 0) {
925     MCSectionData *&Entry = SectionMap[&Section];
926
927     if (Created) *Created = !Entry;
928     if (!Entry)
929       Entry = new MCSectionData(Section, this);
930
931     return *Entry;
932   }
933
934   MCSymbolData &getSymbolData(const MCSymbol &Symbol) const {
935     MCSymbolData *Entry = SymbolMap.lookup(&Symbol);
936     assert(Entry && "Missing symbol data!");
937     return *Entry;
938   }
939
940   MCSymbolData &getOrCreateSymbolData(const MCSymbol &Symbol,
941                                       bool *Created = 0) {
942     MCSymbolData *&Entry = SymbolMap[&Symbol];
943
944     if (Created) *Created = !Entry;
945     if (!Entry)
946       Entry = new MCSymbolData(Symbol, 0, 0, this);
947
948     return *Entry;
949   }
950
951   /// @}
952
953   void dump();
954 };
955
956 } // end namespace llvm
957
958 #endif