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
24namespace mcld {
25class Layout;
26}
27
28namespace llvm {
29class raw_ostream;
30class MCAsmLayout;
31class MCAssembler;
32class MCContext;
33class MCCodeEmitter;
34class MCExpr;
35class MCFragment;
36class MCObjectWriter;
37class MCSection;
38class MCSectionData;
39class MCSymbol;
40class MCSymbolData;
41class MCValue;
42class MCAsmBackend;
43
44class MCFragment : public ilist_node<MCFragment> {
45  friend class MCAsmLayout;
46  friend class mcld::Layout;
47
48  MCFragment(const MCFragment&) LLVM_DELETED_FUNCTION;
49  void operator=(const MCFragment&) LLVM_DELETED_FUNCTION;
50
51public:
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
66private:
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
91protected:
92  MCFragment(FragmentType _Kind, MCSectionData *_Parent = 0);
93
94public:
95  // Only for sentinel.
96  MCFragment();
97  virtual ~MCFragment();
98
99  FragmentType getKind() const { return Kind; }
100
101  MCSectionData *getParent() const { return Parent; }
102  void setParent(MCSectionData *Value) { Parent = Value; }
103
104  MCSymbolData *getAtom() const { return Atom; }
105  void setAtom(MCSymbolData *Value) { Atom = Value; }
106
107  unsigned getLayoutOrder() const { return LayoutOrder; }
108  void setLayoutOrder(unsigned Value) { LayoutOrder = Value; }
109
110  static bool classof(const MCFragment *O) { return true; }
111
112  void dump();
113};
114
115class 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
122public:
123  typedef std::vector<MCFixup>::const_iterator const_fixup_iterator;
124  typedef std::vector<MCFixup>::iterator fixup_iterator;
125
126public:
127  MCDataFragment(MCSectionData *SD = 0) : MCFragment(FT_Data, SD) {}
128
129  /// @name Accessors
130  /// @{
131
132  SmallString<32> &getContents() { return Contents; }
133  const SmallString<32> &getContents() const { return Contents; }
134
135  /// @}
136  /// @name Fixup Access
137  /// @{
138
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
146  std::vector<MCFixup> &getFixups() { return Fixups; }
147  const std::vector<MCFixup> &getFixups() const { return Fixups; }
148
149  fixup_iterator fixup_begin() { return Fixups.begin(); }
150  const_fixup_iterator fixup_begin() const { return Fixups.begin(); }
151
152  fixup_iterator fixup_end() {return Fixups.end();}
153  const_fixup_iterator fixup_end() const {return Fixups.end();}
154
155  size_t fixup_size() const { return Fixups.size(); }
156
157  /// @}
158
159  static bool classof(const MCFragment *F) {
160    return F->getKind() == MCFragment::FT_Data;
161  }
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.
170class 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
182public:
183  typedef SmallVectorImpl<MCFixup>::const_iterator const_fixup_iterator;
184  typedef SmallVectorImpl<MCFixup>::iterator fixup_iterator;
185
186public:
187  MCInstFragment(const MCInst &_Inst, MCSectionData *SD = 0)
188    : MCFragment(FT_Inst, SD), Inst(_Inst) {
189  }
190
191  /// @name Accessors
192  /// @{
193
194  SmallVectorImpl<char> &getCode() { return Code; }
195  const SmallVectorImpl<char> &getCode() const { return Code; }
196
197  unsigned getInstSize() const { return Code.size(); }
198
199  MCInst &getInst() { return Inst; }
200  const MCInst &getInst() const { return Inst; }
201
202  void setInst(const MCInst& Value) { Inst = Value; }
203
204  /// @}
205  /// @name Fixup Access
206  /// @{
207
208  SmallVectorImpl<MCFixup> &getFixups() { return Fixups; }
209  const SmallVectorImpl<MCFixup> &getFixups() const { return Fixups; }
210
211  fixup_iterator fixup_begin() { return Fixups.begin(); }
212  const_fixup_iterator fixup_begin() const { return Fixups.begin(); }
213
214  fixup_iterator fixup_end() {return Fixups.end();}
215  const_fixup_iterator fixup_end() const {return Fixups.end();}
216
217  size_t fixup_size() const { return Fixups.size(); }
218
219  /// @}
220
221  static bool classof(const MCFragment *F) {
222    return F->getKind() == MCFragment::FT_Inst;
223  }
224  static bool classof(const MCInstFragment *) { return true; }
225};
226
227class 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
248public:
249  MCAlignFragment(unsigned _Alignment, int64_t _Value, unsigned _ValueSize,
250                  unsigned _MaxBytesToEmit, MCSectionData *SD = 0)
251    : MCFragment(FT_Align, SD), Alignment(_Alignment),
252      Value(_Value),ValueSize(_ValueSize),
253      MaxBytesToEmit(_MaxBytesToEmit), EmitNops(false) {}
254
255  /// @name Accessors
256  /// @{
257
258  unsigned getAlignment() const { return Alignment; }
259
260  int64_t getValue() const { return Value; }
261
262  unsigned getValueSize() const { return ValueSize; }
263
264  unsigned getMaxBytesToEmit() const { return MaxBytesToEmit; }
265
266  bool hasEmitNops() const { return EmitNops; }
267  void setEmitNops(bool Value) { EmitNops = Value; }
268
269  /// @}
270
271  static bool classof(const MCFragment *F) {
272    return F->getKind() == MCFragment::FT_Align;
273  }
274  static bool classof(const MCAlignFragment *) { return true; }
275};
276
277class MCFillFragment : public MCFragment {
278  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
290public:
291  MCFillFragment(int64_t _Value, unsigned _ValueSize, uint64_t _Size,
292                 MCSectionData *SD = 0)
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
302  int64_t getValue() const { return Value; }
303
304  unsigned getValueSize() const { return ValueSize; }
305
306  uint64_t getSize() const { return Size; }
307
308  /// @}
309
310  static bool classof(const MCFragment *F) {
311    return F->getKind() == MCFragment::FT_Fill;
312  }
313  static bool classof(const MCFillFragment *) { return true; }
314};
315
316class 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
325public:
326  MCOrgFragment(const MCExpr &_Offset, int8_t _Value, MCSectionData *SD = 0)
327    : MCFragment(FT_Org, SD),
328      Offset(&_Offset), Value(_Value) {}
329
330  /// @name Accessors
331  /// @{
332
333  const MCExpr &getOffset() const { return *Offset; }
334
335  uint8_t getValue() const { return Value; }
336
337  /// @}
338
339  static bool classof(const MCFragment *F) {
340    return F->getKind() == MCFragment::FT_Org;
341  }
342  static bool classof(const MCOrgFragment *) { return true; }
343};
344
345class 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;
355public:
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
363  const MCExpr &getValue() const { return *Value; }
364
365  bool isSigned() const { return IsSigned; }
366
367  SmallString<8> &getContents() { return Contents; }
368  const SmallString<8> &getContents() const { return Contents; }
369
370  /// @}
371
372  static bool classof(const MCFragment *F) {
373    return F->getKind() == MCFragment::FT_LEB;
374  }
375  static bool classof(const MCLEBFragment *) { return true; }
376};
377
378class 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
391public:
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
400  int64_t getLineDelta() const { return LineDelta; }
401
402  const MCExpr &getAddrDelta() const { return *AddrDelta; }
403
404  SmallString<8> &getContents() { return Contents; }
405  const SmallString<8> &getContents() const { return Contents; }
406
407  /// @}
408
409  static bool classof(const MCFragment *F) {
410    return F->getKind() == MCFragment::FT_Dwarf;
411  }
412  static bool classof(const MCDwarfLineAddrFragment *) { return true; }
413};
414
415class 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
424public:
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
432  const MCExpr &getAddrDelta() const { return *AddrDelta; }
433
434  SmallString<8> &getContents() { return Contents; }
435  const SmallString<8> &getContents() const { return Contents; }
436
437  /// @}
438
439  static bool classof(const MCFragment *F) {
440    return F->getKind() == MCFragment::FT_DwarfFrame;
441  }
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.
448class 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
454public:
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
463private:
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
487public:
488  // Only for use as sentinel.
489  MCSectionData();
490  MCSectionData(const MCSection &Section, MCAssembler *A = 0);
491
492  const MCSection &getSection() const { return *Section; }
493
494  unsigned getAlignment() const { return Alignment; }
495  void setAlignment(unsigned Value) { Alignment = Value; }
496
497  bool hasInstructions() const { return HasInstructions; }
498  void setHasInstructions(bool Value) { HasInstructions = Value; }
499
500  unsigned getOrdinal() const { return Ordinal; }
501  void setOrdinal(unsigned Value) { Ordinal = Value; }
502
503  unsigned getLayoutOrder() const { return LayoutOrder; }
504  void setLayoutOrder(unsigned Value) { LayoutOrder = Value; }
505
506  /// @name Fragment Access
507  /// @{
508
509  const FragmentListType &getFragmentList() const { return Fragments; }
510  FragmentListType &getFragmentList() { return Fragments; }
511
512  iterator begin() { return Fragments.begin(); }
513  const_iterator begin() const { return Fragments.begin(); }
514
515  iterator end() { return Fragments.end(); }
516  const_iterator end() const { return Fragments.end(); }
517
518  reverse_iterator rbegin() { return Fragments.rbegin(); }
519  const_reverse_iterator rbegin() const { return Fragments.rbegin(); }
520
521  reverse_iterator rend() { return Fragments.rend(); }
522  const_reverse_iterator rend() const { return Fragments.rend(); }
523
524  size_t size() const { return Fragments.size(); }
525
526  bool empty() const { return Fragments.empty(); }
527
528  void dump();
529
530  /// @}
531};
532
533// FIXME: Same concerns as with SectionData.
534class MCSymbolData : public ilist_node<MCSymbolData> {
535public:
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
574public:
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
583  const MCSymbol &getSymbol() const { return *Symbol; }
584
585  MCFragment *getFragment() const { return Fragment; }
586  void setFragment(MCFragment *Value) { Fragment = Value; }
587
588  uint64_t getOffset() const { return Offset; }
589  void setOffset(uint64_t Value) { Offset = Value; }
590
591  /// @}
592  /// @name Symbol Attributes
593  /// @{
594
595  bool isExternal() const { return IsExternal; }
596  void setExternal(bool Value) { IsExternal = Value; }
597
598  bool isPrivateExtern() const { return IsPrivateExtern; }
599  void setPrivateExtern(bool Value) { IsPrivateExtern = Value; }
600
601  /// isCommon - Is this a 'common' symbol.
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.
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.
614  uint64_t getCommonSize() const {
615    assert(isCommon() && "Not a 'common' symbol!");
616    return CommonSize;
617  }
618
619  void setSize(const MCExpr *SS) {
620    SymbolSize = SS;
621  }
622
623  const MCExpr *getSize() const {
624    return SymbolSize;
625  }
626
627
628  /// getCommonAlignment - Return the alignment of a 'common' symbol.
629  unsigned getCommonAlignment() const {
630    assert(isCommon() && "Not a 'common' symbol!");
631    return CommonAlign;
632  }
633
634  /// getFlags - Get the (implementation defined) symbol flags.
635  uint32_t getFlags() const { return Flags; }
636
637  /// setFlags - Set the (implementation defined) symbol flags.
638  void setFlags(uint32_t Value) { Flags = Value; }
639
640  /// modifyFlags - Modify the flags via a mask
641  void modifyFlags(uint32_t Value, uint32_t Mask) {
642    Flags = (Flags & ~Mask) | Value;
643  }
644
645  /// getIndex - Get the (implementation defined) index.
646  uint64_t getIndex() const { return Index; }
647
648  /// setIndex - Set the (implementation defined) index.
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.
657struct IndirectSymbolData {
658  MCSymbol *Symbol;
659  MCSectionData *SectionData;
660};
661
662// FIXME: Ditto this. Purely so the Streamer and the ObjectWriter can talk
663// to one another.
664struct DataRegionData {
665  // This enum should be kept in sync w/ the mach-o definition in
666  // llvm/Object/MachOFormat.h.
667  enum KindTy { Data = 1, JumpTable8, JumpTable16, JumpTable32 } Kind;
668  MCSymbol *Start;
669  MCSymbol *End;
670};
671
672class MCAssembler {
673  friend class MCAsmLayout;
674
675public:
676  typedef iplist<MCSectionData> SectionDataListType;
677  typedef iplist<MCSymbolData> SymbolDataListType;
678
679  typedef SectionDataListType::const_iterator const_iterator;
680  typedef SectionDataListType::iterator iterator;
681
682  typedef SymbolDataListType::const_iterator const_symbol_iterator;
683  typedef SymbolDataListType::iterator symbol_iterator;
684
685  typedef std::vector<IndirectSymbolData>::const_iterator
686    const_indirect_symbol_iterator;
687  typedef std::vector<IndirectSymbolData>::iterator indirect_symbol_iterator;
688
689  typedef std::vector<DataRegionData>::const_iterator
690    const_data_region_iterator;
691  typedef std::vector<DataRegionData>::iterator data_region_iterator;
692
693private:
694  MCAssembler(const MCAssembler&);    // DO NOT IMPLEMENT
695  void operator=(const MCAssembler&); // DO NOT IMPLEMENT
696
697  MCContext &Context;
698
699  MCAsmBackend &Backend;
700
701  MCCodeEmitter &Emitter;
702
703  MCObjectWriter *Writer;
704
705  raw_ostream &OS;
706
707  iplist<MCSectionData> Sections;
708
709  iplist<MCSymbolData> Symbols;
710
711  /// The map of sections to their associated assembler backend data.
712  //
713  // FIXME: Avoid this indirection?
714  DenseMap<const MCSection*, MCSectionData*> SectionMap;
715
716  /// The map of symbols to their associated assembler backend data.
717  //
718  // FIXME: Avoid this indirection?
719  DenseMap<const MCSymbol*, MCSymbolData*> SymbolMap;
720
721  std::vector<IndirectSymbolData> IndirectSymbols;
722
723  std::vector<DataRegionData> DataRegions;
724  /// The set of function symbols for which a .thumb_func directive has
725  /// been seen.
726  //
727  // FIXME: We really would like this in target specific code rather than
728  // here. Maybe when the relocation stuff moves to target specific,
729  // this can go with it? The streamer would need some target specific
730  // refactoring too.
731  SmallPtrSet<const MCSymbol*, 64> ThumbFuncs;
732
733  unsigned RelaxAll : 1;
734  unsigned NoExecStack : 1;
735  unsigned SubsectionsViaSymbols : 1;
736
737private:
738  /// Evaluate a fixup to a relocatable expression and the value which should be
739  /// placed into the fixup.
740  ///
741  /// \param Layout The layout to use for evaluation.
742  /// \param Fixup The fixup to evaluate.
743  /// \param DF The fragment the fixup is inside.
744  /// \param Target [out] On return, the relocatable expression the fixup
745  /// evaluates to.
746  /// \param Value [out] On return, the value of the fixup as currently laid
747  /// out.
748  /// \return Whether the fixup value was fully resolved. This is true if the
749  /// \arg Value result is fixed, otherwise the value may change due to
750  /// relocation.
751  bool evaluateFixup(const MCAsmLayout &Layout,
752                     const MCFixup &Fixup, const MCFragment *DF,
753                     MCValue &Target, uint64_t &Value) const;
754
755  /// Check whether a fixup can be satisfied, or whether it needs to be relaxed
756  /// (increased in size, in order to hold its value correctly).
757  bool fixupNeedsRelaxation(const MCFixup &Fixup, const MCInstFragment *DF,
758                            const MCAsmLayout &Layout) const;
759
760  /// Check whether the given fragment needs relaxation.
761  bool fragmentNeedsRelaxation(const MCInstFragment *IF,
762                               const MCAsmLayout &Layout) const;
763
764  /// layoutOnce - Perform one layout iteration and return true if any offsets
765  /// were adjusted.
766  bool layoutOnce(MCAsmLayout &Layout);
767
768  bool layoutSectionOnce(MCAsmLayout &Layout, MCSectionData &SD);
769
770  bool relaxInstruction(MCAsmLayout &Layout, MCInstFragment &IF);
771
772  bool relaxLEB(MCAsmLayout &Layout, MCLEBFragment &IF);
773
774  bool relaxDwarfLineAddr(MCAsmLayout &Layout, MCDwarfLineAddrFragment &DF);
775  bool relaxDwarfCallFrameFragment(MCAsmLayout &Layout,
776                                   MCDwarfCallFrameFragment &DF);
777
778  /// finishLayout - Finalize a layout, including fragment lowering.
779  void finishLayout(MCAsmLayout &Layout);
780
781  uint64_t handleFixup(const MCAsmLayout &Layout,
782                       MCFragment &F, const MCFixup &Fixup);
783
784public:
785  /// Compute the effective fragment size assuming it is laid out at the given
786  /// \arg SectionAddress and \arg FragmentOffset.
787  uint64_t computeFragmentSize(const MCAsmLayout &Layout,
788                               const MCFragment &F) const;
789
790  /// Find the symbol which defines the atom containing the given symbol, or
791  /// null if there is no such symbol.
792  const MCSymbolData *getAtom(const MCSymbolData *Symbol) const;
793
794  /// Check whether a particular symbol is visible to the linker and is required
795  /// in the symbol table, or whether it can be discarded by the assembler. This
796  /// also effects whether the assembler treats the label as potentially
797  /// defining a separate atom.
798  bool isSymbolLinkerVisible(const MCSymbol &SD) const;
799
800  /// Emit the section contents using the given object writer.
801  void writeSectionData(const MCSectionData *Section,
802                        const MCAsmLayout &Layout) const;
803
804  /// Check whether a given symbol has been flagged with .thumb_func.
805  bool isThumbFunc(const MCSymbol *Func) const {
806    return ThumbFuncs.count(Func);
807  }
808
809  /// Flag a function symbol as the target of a .thumb_func directive.
810  void setIsThumbFunc(const MCSymbol *Func) { ThumbFuncs.insert(Func); }
811
812public:
813  /// Construct a new assembler instance.
814  ///
815  /// \arg OS - The stream to output to.
816  //
817  // FIXME: How are we going to parameterize this? Two obvious options are stay
818  // concrete and require clients to pass in a target like object. The other
819  // option is to make this abstract, and have targets provide concrete
820  // implementations as we do with AsmParser.
821  MCAssembler(MCContext &Context_, MCAsmBackend &Backend_,
822              MCCodeEmitter &Emitter_, MCObjectWriter &Writer_,
823              raw_ostream &OS);
824  ~MCAssembler();
825
826  MCContext &getContext() const { return Context; }
827
828  MCAsmBackend &getBackend() const { return Backend; }
829
830  MCCodeEmitter &getEmitter() const { return Emitter; }
831
832  MCObjectWriter &getWriter() const { return *Writer; }
833
834  void setWriter(MCObjectWriter &ObjectWriter);
835
836  /// Finish - Do final processing and write the object to the output stream.
837  /// \arg Writer is used for custom object writer (as the MCJIT does),
838  /// if not specified it is automatically created from backend.
839  void Finish();
840
841  // FIXME: This does not belong here.
842  bool getSubsectionsViaSymbols() const {
843    return SubsectionsViaSymbols;
844  }
845  void setSubsectionsViaSymbols(bool Value) {
846    SubsectionsViaSymbols = Value;
847  }
848
849  bool getRelaxAll() const { return RelaxAll; }
850  void setRelaxAll(bool Value) { RelaxAll = Value; }
851
852  bool getNoExecStack() const { return NoExecStack; }
853  void setNoExecStack(bool Value) { NoExecStack = Value; }
854
855  /// @name Section List Access
856  /// @{
857
858  const SectionDataListType &getSectionList() const { return Sections; }
859  SectionDataListType &getSectionList() { return Sections; }
860
861  iterator begin() { return Sections.begin(); }
862  const_iterator begin() const { return Sections.begin(); }
863
864  iterator end() { return Sections.end(); }
865  const_iterator end() const { return Sections.end(); }
866
867  size_t size() const { return Sections.size(); }
868
869  /// @}
870  /// @name Symbol List Access
871  /// @{
872
873  const SymbolDataListType &getSymbolList() const { return Symbols; }
874  SymbolDataListType &getSymbolList() { return Symbols; }
875
876  symbol_iterator symbol_begin() { return Symbols.begin(); }
877  const_symbol_iterator symbol_begin() const { return Symbols.begin(); }
878
879  symbol_iterator symbol_end() { return Symbols.end(); }
880  const_symbol_iterator symbol_end() const { return Symbols.end(); }
881
882  size_t symbol_size() const { return Symbols.size(); }
883
884  /// @}
885  /// @name Indirect Symbol List Access
886  /// @{
887
888  // FIXME: This is a total hack, this should not be here. Once things are
889  // factored so that the streamer has direct access to the .o writer, it can
890  // disappear.
891  std::vector<IndirectSymbolData> &getIndirectSymbols() {
892    return IndirectSymbols;
893  }
894
895  indirect_symbol_iterator indirect_symbol_begin() {
896    return IndirectSymbols.begin();
897  }
898  const_indirect_symbol_iterator indirect_symbol_begin() const {
899    return IndirectSymbols.begin();
900  }
901
902  indirect_symbol_iterator indirect_symbol_end() {
903    return IndirectSymbols.end();
904  }
905  const_indirect_symbol_iterator indirect_symbol_end() const {
906    return IndirectSymbols.end();
907  }
908
909  size_t indirect_symbol_size() const { return IndirectSymbols.size(); }
910
911  /// @}
912  /// @name Data Region List Access
913  /// @{
914
915  // FIXME: This is a total hack, this should not be here. Once things are
916  // factored so that the streamer has direct access to the .o writer, it can
917  // disappear.
918  std::vector<DataRegionData> &getDataRegions() {
919    return DataRegions;
920  }
921
922  data_region_iterator data_region_begin() {
923    return DataRegions.begin();
924  }
925  const_data_region_iterator data_region_begin() const {
926    return DataRegions.begin();
927  }
928
929  data_region_iterator data_region_end() {
930    return DataRegions.end();
931  }
932  const_data_region_iterator data_region_end() const {
933    return DataRegions.end();
934  }
935
936  size_t data_region_size() const { return DataRegions.size(); }
937
938  /// @}
939  /// @name Backend Data Access
940  /// @{
941
942  MCSectionData &getSectionData(const MCSection &Section) const {
943    MCSectionData *Entry = SectionMap.lookup(&Section);
944    assert(Entry && "Missing section data!");
945    return *Entry;
946  }
947
948  MCSectionData &getOrCreateSectionData(const MCSection &Section,
949                                        bool *Created = 0) {
950    MCSectionData *&Entry = SectionMap[&Section];
951
952    if (Created) *Created = !Entry;
953    if (!Entry)
954      Entry = new MCSectionData(Section, this);
955
956    return *Entry;
957  }
958
959  MCSymbolData &getSymbolData(const MCSymbol &Symbol) const {
960    MCSymbolData *Entry = SymbolMap.lookup(&Symbol);
961    assert(Entry && "Missing symbol data!");
962    return *Entry;
963  }
964
965  MCSymbolData &getOrCreateSymbolData(const MCSymbol &Symbol,
966                                      bool *Created = 0) {
967    MCSymbolData *&Entry = SymbolMap[&Symbol];
968
969    if (Created) *Created = !Entry;
970    if (!Entry)
971      Entry = new MCSymbolData(Symbol, 0, 0, this);
972
973    return *Entry;
974  }
975
976  /// @}
977
978  void dump();
979};
980
981} // end namespace llvm
982
983#endif
984