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