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