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