LLVM API Documentation

MCAssembler.h
Go to the documentation of this file.
00001 //===- MCAssembler.h - Object File Generation -------------------*- C++ -*-===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 
00010 #ifndef LLVM_MC_MCASSEMBLER_H
00011 #define LLVM_MC_MCASSEMBLER_H
00012 
00013 #include "llvm/ADT/DenseMap.h"
00014 #include "llvm/ADT/SmallPtrSet.h"
00015 #include "llvm/ADT/SmallString.h"
00016 #include "llvm/ADT/ilist.h"
00017 #include "llvm/ADT/ilist_node.h"
00018 #include "llvm/MC/MCFixup.h"
00019 #include "llvm/MC/MCInst.h"
00020 #include "llvm/Support/Casting.h"
00021 #include "llvm/Support/DataTypes.h"
00022 #include <vector> // FIXME: Shouldn't be needed.
00023 
00024 namespace llvm {
00025 class raw_ostream;
00026 class MCAsmLayout;
00027 class MCAssembler;
00028 class MCContext;
00029 class MCCodeEmitter;
00030 class MCExpr;
00031 class MCFragment;
00032 class MCObjectWriter;
00033 class MCSection;
00034 class MCSectionData;
00035 class MCSymbol;
00036 class MCSymbolData;
00037 class MCValue;
00038 class MCAsmBackend;
00039 
00040 class MCFragment : public ilist_node<MCFragment> {
00041   friend class MCAsmLayout;
00042 
00043   MCFragment(const MCFragment&) LLVM_DELETED_FUNCTION;
00044   void operator=(const MCFragment&) LLVM_DELETED_FUNCTION;
00045 
00046 public:
00047   enum FragmentType {
00048     FT_Align,
00049     FT_Data,
00050     FT_CompactEncodedInst,
00051     FT_Fill,
00052     FT_Relaxable,
00053     FT_Org,
00054     FT_Dwarf,
00055     FT_DwarfFrame,
00056     FT_LEB
00057   };
00058 
00059 private:
00060   FragmentType Kind;
00061 
00062   /// Parent - The data for the section this fragment is in.
00063   MCSectionData *Parent;
00064 
00065   /// Atom - The atom this fragment is in, as represented by it's defining
00066   /// symbol. Atom's are only used by backends which set
00067   /// \see MCAsmBackend::hasReliableSymbolDifference().
00068   MCSymbolData *Atom;
00069 
00070   /// @name Assembler Backend Data
00071   /// @{
00072   //
00073   // FIXME: This could all be kept private to the assembler implementation.
00074 
00075   /// Offset - The offset of this fragment in its section. This is ~0 until
00076   /// initialized.
00077   uint64_t Offset;
00078 
00079   /// LayoutOrder - The layout order of this fragment.
00080   unsigned LayoutOrder;
00081 
00082   /// @}
00083 
00084 protected:
00085   MCFragment(FragmentType _Kind, MCSectionData *_Parent = 0);
00086 
00087 public:
00088   // Only for sentinel.
00089   MCFragment();
00090   virtual ~MCFragment();
00091 
00092   FragmentType getKind() const { return Kind; }
00093 
00094   MCSectionData *getParent() const { return Parent; }
00095   void setParent(MCSectionData *Value) { Parent = Value; }
00096 
00097   MCSymbolData *getAtom() const { return Atom; }
00098   void setAtom(MCSymbolData *Value) { Atom = Value; }
00099 
00100   unsigned getLayoutOrder() const { return LayoutOrder; }
00101   void setLayoutOrder(unsigned Value) { LayoutOrder = Value; }
00102 
00103   /// \brief Does this fragment have instructions emitted into it? By default
00104   /// this is false, but specific fragment types may set it to true.
00105   virtual bool hasInstructions() const { return false; }
00106 
00107   /// \brief Should this fragment be placed at the end of an aligned bundle?
00108   virtual bool alignToBundleEnd() const { return false; }
00109   virtual void setAlignToBundleEnd(bool V) { }
00110 
00111   /// \brief Get the padding size that must be inserted before this fragment.
00112   /// Used for bundling. By default, no padding is inserted.
00113   /// Note that padding size is restricted to 8 bits. This is an optimization
00114   /// to reduce the amount of space used for each fragment. In practice, larger
00115   /// padding should never be required.
00116   virtual uint8_t getBundlePadding() const {
00117     return 0;
00118   }
00119 
00120   /// \brief Set the padding size for this fragment. By default it's a no-op,
00121   /// and only some fragments have a meaningful implementation.
00122   virtual void setBundlePadding(uint8_t N) {
00123   }
00124 
00125   void dump();
00126 };
00127 
00128 /// Interface implemented by fragments that contain encoded instructions and/or
00129 /// data.
00130 ///
00131 class MCEncodedFragment : public MCFragment {
00132   virtual void anchor();
00133 
00134   uint8_t BundlePadding;
00135 public:
00136   MCEncodedFragment(MCFragment::FragmentType FType, MCSectionData *SD = 0)
00137     : MCFragment(FType, SD), BundlePadding(0)
00138   {
00139   }
00140   virtual ~MCEncodedFragment();
00141 
00142   virtual SmallVectorImpl<char> &getContents() = 0;
00143   virtual const SmallVectorImpl<char> &getContents() const = 0;
00144 
00145   virtual uint8_t getBundlePadding() const {
00146     return BundlePadding;
00147   }
00148 
00149   virtual void setBundlePadding(uint8_t N) {
00150     BundlePadding = N;
00151   }
00152 
00153   static bool classof(const MCFragment *F) {
00154     MCFragment::FragmentType Kind = F->getKind();
00155     switch (Kind) {
00156       default:
00157         return false;
00158       case MCFragment::FT_Relaxable:
00159       case MCFragment::FT_CompactEncodedInst:
00160       case MCFragment::FT_Data:
00161         return true;
00162     }
00163   }
00164 };
00165 
00166 /// Interface implemented by fragments that contain encoded instructions and/or
00167 /// data and also have fixups registered.
00168 ///
00169 class MCEncodedFragmentWithFixups : public MCEncodedFragment {
00170   virtual void anchor();
00171 
00172 public:
00173   MCEncodedFragmentWithFixups(MCFragment::FragmentType FType,
00174                               MCSectionData *SD = 0)
00175     : MCEncodedFragment(FType, SD)
00176   {
00177   }
00178 
00179   virtual ~MCEncodedFragmentWithFixups();
00180 
00181   typedef SmallVectorImpl<MCFixup>::const_iterator const_fixup_iterator;
00182   typedef SmallVectorImpl<MCFixup>::iterator fixup_iterator;
00183 
00184   virtual SmallVectorImpl<MCFixup> &getFixups() = 0;
00185   virtual const SmallVectorImpl<MCFixup> &getFixups() const = 0;
00186 
00187   virtual fixup_iterator fixup_begin() = 0;
00188   virtual const_fixup_iterator fixup_begin() const  = 0;
00189   virtual fixup_iterator fixup_end() = 0;
00190   virtual const_fixup_iterator fixup_end() const = 0;
00191 
00192   static bool classof(const MCFragment *F) {
00193     MCFragment::FragmentType Kind = F->getKind();
00194     return Kind == MCFragment::FT_Relaxable || Kind == MCFragment::FT_Data;
00195   }
00196 };
00197 
00198 /// Fragment for data and encoded instructions.
00199 ///
00200 class MCDataFragment : public MCEncodedFragmentWithFixups {
00201   virtual void anchor();
00202 
00203   /// \brief Does this fragment contain encoded instructions anywhere in it?
00204   bool HasInstructions;
00205 
00206   /// \brief Should this fragment be aligned to the end of a bundle?
00207   bool AlignToBundleEnd;
00208 
00209   SmallVector<char, 32> Contents;
00210 
00211   /// Fixups - The list of fixups in this fragment.
00212   SmallVector<MCFixup, 4> Fixups;
00213 public:
00214   MCDataFragment(MCSectionData *SD = 0)
00215     : MCEncodedFragmentWithFixups(FT_Data, SD),
00216       HasInstructions(false), AlignToBundleEnd(false)
00217   {
00218   }
00219 
00220   virtual SmallVectorImpl<char> &getContents() { return Contents; }
00221   virtual const SmallVectorImpl<char> &getContents() const { return Contents; }
00222 
00223   SmallVectorImpl<MCFixup> &getFixups() {
00224     return Fixups;
00225   }
00226 
00227   const SmallVectorImpl<MCFixup> &getFixups() const {
00228     return Fixups;
00229   }
00230 
00231   virtual bool hasInstructions() const { return HasInstructions; }
00232   virtual void setHasInstructions(bool V) { HasInstructions = V; }
00233 
00234   virtual bool alignToBundleEnd() const { return AlignToBundleEnd; }
00235   virtual void setAlignToBundleEnd(bool V) { AlignToBundleEnd = V; }
00236 
00237   fixup_iterator fixup_begin() { return Fixups.begin(); }
00238   const_fixup_iterator fixup_begin() const { return Fixups.begin(); }
00239 
00240   fixup_iterator fixup_end() {return Fixups.end();}
00241   const_fixup_iterator fixup_end() const {return Fixups.end();}
00242 
00243   static bool classof(const MCFragment *F) {
00244     return F->getKind() == MCFragment::FT_Data;
00245   }
00246 };
00247 
00248 /// This is a compact (memory-size-wise) fragment for holding an encoded
00249 /// instruction (non-relaxable) that has no fixups registered. When applicable,
00250 /// it can be used instead of MCDataFragment and lead to lower memory
00251 /// consumption.
00252 ///
00253 class MCCompactEncodedInstFragment : public MCEncodedFragment {
00254   virtual void anchor();
00255 
00256   /// \brief Should this fragment be aligned to the end of a bundle?
00257   bool AlignToBundleEnd;
00258 
00259   SmallVector<char, 4> Contents;
00260 public:
00261   MCCompactEncodedInstFragment(MCSectionData *SD = 0)
00262     : MCEncodedFragment(FT_CompactEncodedInst, SD), AlignToBundleEnd(false)
00263   {
00264   }
00265 
00266   virtual bool hasInstructions() const {
00267     return true;
00268   }
00269 
00270   virtual SmallVectorImpl<char> &getContents() { return Contents; }
00271   virtual const SmallVectorImpl<char> &getContents() const { return Contents; }
00272 
00273   virtual bool alignToBundleEnd() const { return AlignToBundleEnd; }
00274   virtual void setAlignToBundleEnd(bool V) { AlignToBundleEnd = V; }
00275 
00276   static bool classof(const MCFragment *F) {
00277     return F->getKind() == MCFragment::FT_CompactEncodedInst;
00278   }
00279 };
00280 
00281 /// A relaxable fragment holds on to its MCInst, since it may need to be
00282 /// relaxed during the assembler layout and relaxation stage.
00283 ///
00284 class MCRelaxableFragment : public MCEncodedFragmentWithFixups {
00285   virtual void anchor();
00286 
00287   /// Inst - The instruction this is a fragment for.
00288   MCInst Inst;
00289 
00290   /// Contents - Binary data for the currently encoded instruction.
00291   SmallVector<char, 8> Contents;
00292 
00293   /// Fixups - The list of fixups in this fragment.
00294   SmallVector<MCFixup, 1> Fixups;
00295 
00296 public:
00297   MCRelaxableFragment(const MCInst &_Inst, MCSectionData *SD = 0)
00298     : MCEncodedFragmentWithFixups(FT_Relaxable, SD), Inst(_Inst) {
00299   }
00300 
00301   virtual SmallVectorImpl<char> &getContents() { return Contents; }
00302   virtual const SmallVectorImpl<char> &getContents() const { return Contents; }
00303 
00304   const MCInst &getInst() const { return Inst; }
00305   void setInst(const MCInst& Value) { Inst = Value; }
00306 
00307   SmallVectorImpl<MCFixup> &getFixups() {
00308     return Fixups;
00309   }
00310 
00311   const SmallVectorImpl<MCFixup> &getFixups() const {
00312     return Fixups;
00313   }
00314 
00315   virtual bool hasInstructions() const { return true; }
00316 
00317   fixup_iterator fixup_begin() { return Fixups.begin(); }
00318   const_fixup_iterator fixup_begin() const { return Fixups.begin(); }
00319 
00320   fixup_iterator fixup_end() {return Fixups.end();}
00321   const_fixup_iterator fixup_end() const {return Fixups.end();}
00322 
00323   static bool classof(const MCFragment *F) {
00324     return F->getKind() == MCFragment::FT_Relaxable;
00325   }
00326 };
00327 
00328 class MCAlignFragment : public MCFragment {
00329   virtual void anchor();
00330 
00331   /// Alignment - The alignment to ensure, in bytes.
00332   unsigned Alignment;
00333 
00334   /// Value - Value to use for filling padding bytes.
00335   int64_t Value;
00336 
00337   /// ValueSize - The size of the integer (in bytes) of \p Value.
00338   unsigned ValueSize;
00339 
00340   /// MaxBytesToEmit - The maximum number of bytes to emit; if the alignment
00341   /// cannot be satisfied in this width then this fragment is ignored.
00342   unsigned MaxBytesToEmit;
00343 
00344   /// EmitNops - Flag to indicate that (optimal) NOPs should be emitted instead
00345   /// of using the provided value. The exact interpretation of this flag is
00346   /// target dependent.
00347   bool EmitNops : 1;
00348 
00349 public:
00350   MCAlignFragment(unsigned _Alignment, int64_t _Value, unsigned _ValueSize,
00351                   unsigned _MaxBytesToEmit, MCSectionData *SD = 0)
00352     : MCFragment(FT_Align, SD), Alignment(_Alignment),
00353       Value(_Value),ValueSize(_ValueSize),
00354       MaxBytesToEmit(_MaxBytesToEmit), EmitNops(false) {}
00355 
00356   /// @name Accessors
00357   /// @{
00358 
00359   unsigned getAlignment() const { return Alignment; }
00360 
00361   int64_t getValue() const { return Value; }
00362 
00363   unsigned getValueSize() const { return ValueSize; }
00364 
00365   unsigned getMaxBytesToEmit() const { return MaxBytesToEmit; }
00366 
00367   bool hasEmitNops() const { return EmitNops; }
00368   void setEmitNops(bool Value) { EmitNops = Value; }
00369 
00370   /// @}
00371 
00372   static bool classof(const MCFragment *F) {
00373     return F->getKind() == MCFragment::FT_Align;
00374   }
00375 };
00376 
00377 class MCFillFragment : public MCFragment {
00378   virtual void anchor();
00379 
00380   /// Value - Value to use for filling bytes.
00381   int64_t Value;
00382 
00383   /// ValueSize - The size (in bytes) of \p Value to use when filling, or 0 if
00384   /// this is a virtual fill fragment.
00385   unsigned ValueSize;
00386 
00387   /// Size - The number of bytes to insert.
00388   uint64_t Size;
00389 
00390 public:
00391   MCFillFragment(int64_t _Value, unsigned _ValueSize, uint64_t _Size,
00392                  MCSectionData *SD = 0)
00393     : MCFragment(FT_Fill, SD),
00394       Value(_Value), ValueSize(_ValueSize), Size(_Size) {
00395     assert((!ValueSize || (Size % ValueSize) == 0) &&
00396            "Fill size must be a multiple of the value size!");
00397   }
00398 
00399   /// @name Accessors
00400   /// @{
00401 
00402   int64_t getValue() const { return Value; }
00403 
00404   unsigned getValueSize() const { return ValueSize; }
00405 
00406   uint64_t getSize() const { return Size; }
00407 
00408   /// @}
00409 
00410   static bool classof(const MCFragment *F) {
00411     return F->getKind() == MCFragment::FT_Fill;
00412   }
00413 };
00414 
00415 class MCOrgFragment : public MCFragment {
00416   virtual void anchor();
00417 
00418   /// Offset - The offset this fragment should start at.
00419   const MCExpr *Offset;
00420 
00421   /// Value - Value to use for filling bytes.
00422   int8_t Value;
00423 
00424 public:
00425   MCOrgFragment(const MCExpr &_Offset, int8_t _Value, MCSectionData *SD = 0)
00426     : MCFragment(FT_Org, SD),
00427       Offset(&_Offset), Value(_Value) {}
00428 
00429   /// @name Accessors
00430   /// @{
00431 
00432   const MCExpr &getOffset() const { return *Offset; }
00433 
00434   uint8_t getValue() const { return Value; }
00435 
00436   /// @}
00437 
00438   static bool classof(const MCFragment *F) {
00439     return F->getKind() == MCFragment::FT_Org;
00440   }
00441 };
00442 
00443 class MCLEBFragment : public MCFragment {
00444   virtual void anchor();
00445 
00446   /// Value - The value this fragment should contain.
00447   const MCExpr *Value;
00448 
00449   /// IsSigned - True if this is a sleb128, false if uleb128.
00450   bool IsSigned;
00451 
00452   SmallString<8> Contents;
00453 public:
00454   MCLEBFragment(const MCExpr &Value_, bool IsSigned_, MCSectionData *SD = 0)
00455     : MCFragment(FT_LEB, SD),
00456       Value(&Value_), IsSigned(IsSigned_) { Contents.push_back(0); }
00457 
00458   /// @name Accessors
00459   /// @{
00460 
00461   const MCExpr &getValue() const { return *Value; }
00462 
00463   bool isSigned() const { return IsSigned; }
00464 
00465   SmallString<8> &getContents() { return Contents; }
00466   const SmallString<8> &getContents() const { return Contents; }
00467 
00468   /// @}
00469 
00470   static bool classof(const MCFragment *F) {
00471     return F->getKind() == MCFragment::FT_LEB;
00472   }
00473 };
00474 
00475 class MCDwarfLineAddrFragment : public MCFragment {
00476   virtual void anchor();
00477 
00478   /// LineDelta - the value of the difference between the two line numbers
00479   /// between two .loc dwarf directives.
00480   int64_t LineDelta;
00481 
00482   /// AddrDelta - The expression for the difference of the two symbols that
00483   /// make up the address delta between two .loc dwarf directives.
00484   const MCExpr *AddrDelta;
00485 
00486   SmallString<8> Contents;
00487 
00488 public:
00489   MCDwarfLineAddrFragment(int64_t _LineDelta, const MCExpr &_AddrDelta,
00490                       MCSectionData *SD = 0)
00491     : MCFragment(FT_Dwarf, SD),
00492       LineDelta(_LineDelta), AddrDelta(&_AddrDelta) { Contents.push_back(0); }
00493 
00494   /// @name Accessors
00495   /// @{
00496 
00497   int64_t getLineDelta() const { return LineDelta; }
00498 
00499   const MCExpr &getAddrDelta() const { return *AddrDelta; }
00500 
00501   SmallString<8> &getContents() { return Contents; }
00502   const SmallString<8> &getContents() const { return Contents; }
00503 
00504   /// @}
00505 
00506   static bool classof(const MCFragment *F) {
00507     return F->getKind() == MCFragment::FT_Dwarf;
00508   }
00509 };
00510 
00511 class MCDwarfCallFrameFragment : public MCFragment {
00512   virtual void anchor();
00513 
00514   /// AddrDelta - The expression for the difference of the two symbols that
00515   /// make up the address delta between two .cfi_* dwarf directives.
00516   const MCExpr *AddrDelta;
00517 
00518   SmallString<8> Contents;
00519 
00520 public:
00521   MCDwarfCallFrameFragment(const MCExpr &_AddrDelta,  MCSectionData *SD = 0)
00522     : MCFragment(FT_DwarfFrame, SD),
00523       AddrDelta(&_AddrDelta) { Contents.push_back(0); }
00524 
00525   /// @name Accessors
00526   /// @{
00527 
00528   const MCExpr &getAddrDelta() const { return *AddrDelta; }
00529 
00530   SmallString<8> &getContents() { return Contents; }
00531   const SmallString<8> &getContents() const { return Contents; }
00532 
00533   /// @}
00534 
00535   static bool classof(const MCFragment *F) {
00536     return F->getKind() == MCFragment::FT_DwarfFrame;
00537   }
00538 };
00539 
00540 // FIXME: Should this be a separate class, or just merged into MCSection? Since
00541 // we anticipate the fast path being through an MCAssembler, the only reason to
00542 // keep it out is for API abstraction.
00543 class MCSectionData : public ilist_node<MCSectionData> {
00544   friend class MCAsmLayout;
00545 
00546   MCSectionData(const MCSectionData&) LLVM_DELETED_FUNCTION;
00547   void operator=(const MCSectionData&) LLVM_DELETED_FUNCTION;
00548 
00549 public:
00550   typedef iplist<MCFragment> FragmentListType;
00551 
00552   typedef FragmentListType::const_iterator const_iterator;
00553   typedef FragmentListType::iterator iterator;
00554 
00555   typedef FragmentListType::const_reverse_iterator const_reverse_iterator;
00556   typedef FragmentListType::reverse_iterator reverse_iterator;
00557 
00558   /// \brief Express the state of bundle locked groups while emitting code.
00559   enum BundleLockStateType {
00560     NotBundleLocked,
00561     BundleLocked,
00562     BundleLockedAlignToEnd
00563   };
00564 private:
00565   FragmentListType Fragments;
00566   const MCSection *Section;
00567 
00568   /// Ordinal - The section index in the assemblers section list.
00569   unsigned Ordinal;
00570 
00571   /// LayoutOrder - The index of this section in the layout order.
00572   unsigned LayoutOrder;
00573 
00574   /// Alignment - The maximum alignment seen in this section.
00575   unsigned Alignment;
00576 
00577   /// \brief Keeping track of bundle-locked state.
00578   BundleLockStateType BundleLockState; 
00579 
00580   /// \brief We've seen a bundle_lock directive but not its first instruction
00581   /// yet.
00582   bool BundleGroupBeforeFirstInst;
00583 
00584   /// @name Assembler Backend Data
00585   /// @{
00586   //
00587   // FIXME: This could all be kept private to the assembler implementation.
00588 
00589   /// HasInstructions - Whether this section has had instructions emitted into
00590   /// it.
00591   unsigned HasInstructions : 1;
00592 
00593   /// Mapping from subsection number to insertion point for subsection numbers
00594   /// below that number.
00595   SmallVector<std::pair<unsigned, MCFragment *>, 1> SubsectionFragmentMap;
00596 
00597   /// @}
00598 
00599 public:
00600   // Only for use as sentinel.
00601   MCSectionData();
00602   MCSectionData(const MCSection &Section, MCAssembler *A = 0);
00603 
00604   const MCSection &getSection() const { return *Section; }
00605 
00606   unsigned getAlignment() const { return Alignment; }
00607   void setAlignment(unsigned Value) { Alignment = Value; }
00608 
00609   bool hasInstructions() const { return HasInstructions; }
00610   void setHasInstructions(bool Value) { HasInstructions = Value; }
00611 
00612   unsigned getOrdinal() const { return Ordinal; }
00613   void setOrdinal(unsigned Value) { Ordinal = Value; }
00614 
00615   unsigned getLayoutOrder() const { return LayoutOrder; }
00616   void setLayoutOrder(unsigned Value) { LayoutOrder = Value; }
00617 
00618   /// @name Fragment Access
00619   /// @{
00620 
00621   const FragmentListType &getFragmentList() const { return Fragments; }
00622   FragmentListType &getFragmentList() { return Fragments; }
00623 
00624   iterator begin() { return Fragments.begin(); }
00625   const_iterator begin() const { return Fragments.begin(); }
00626 
00627   iterator end() { return Fragments.end(); }
00628   const_iterator end() const { return Fragments.end(); }
00629 
00630   reverse_iterator rbegin() { return Fragments.rbegin(); }
00631   const_reverse_iterator rbegin() const { return Fragments.rbegin(); }
00632 
00633   reverse_iterator rend() { return Fragments.rend(); }
00634   const_reverse_iterator rend() const { return Fragments.rend(); }
00635 
00636   size_t size() const { return Fragments.size(); }
00637 
00638   bool empty() const { return Fragments.empty(); }
00639 
00640   iterator getSubsectionInsertionPoint(unsigned Subsection);
00641 
00642   bool isBundleLocked() const {
00643     return BundleLockState != NotBundleLocked;
00644   }
00645 
00646   BundleLockStateType getBundleLockState() const {
00647     return BundleLockState;
00648   }
00649 
00650   void setBundleLockState(BundleLockStateType NewState) {
00651     BundleLockState = NewState;
00652   }
00653 
00654   bool isBundleGroupBeforeFirstInst() const {
00655     return BundleGroupBeforeFirstInst;
00656   }
00657 
00658   void setBundleGroupBeforeFirstInst(bool IsFirst) {
00659     BundleGroupBeforeFirstInst = IsFirst;
00660   }
00661 
00662   void dump();
00663 
00664   /// @}
00665 };
00666 
00667 // FIXME: Same concerns as with SectionData.
00668 class MCSymbolData : public ilist_node<MCSymbolData> {
00669 public:
00670   const MCSymbol *Symbol;
00671 
00672   /// Fragment - The fragment this symbol's value is relative to, if any.
00673   MCFragment *Fragment;
00674 
00675   /// Offset - The offset to apply to the fragment address to form this symbol's
00676   /// value.
00677   uint64_t Offset;
00678 
00679   /// IsExternal - True if this symbol is visible outside this translation
00680   /// unit.
00681   unsigned IsExternal : 1;
00682 
00683   /// IsPrivateExtern - True if this symbol is private extern.
00684   unsigned IsPrivateExtern : 1;
00685 
00686   /// CommonSize - The size of the symbol, if it is 'common', or 0.
00687   //
00688   // FIXME: Pack this in with other fields? We could put it in offset, since a
00689   // common symbol can never get a definition.
00690   uint64_t CommonSize;
00691 
00692   /// SymbolSize - An expression describing how to calculate the size of
00693   /// a symbol. If a symbol has no size this field will be NULL.
00694   const MCExpr *SymbolSize;
00695 
00696   /// CommonAlign - The alignment of the symbol, if it is 'common'.
00697   //
00698   // FIXME: Pack this in with other fields?
00699   unsigned CommonAlign;
00700 
00701   /// Flags - The Flags field is used by object file implementations to store
00702   /// additional per symbol information which is not easily classified.
00703   uint32_t Flags;
00704 
00705   /// Index - Index field, for use by the object file implementation.
00706   uint64_t Index;
00707 
00708 public:
00709   // Only for use as sentinel.
00710   MCSymbolData();
00711   MCSymbolData(const MCSymbol &_Symbol, MCFragment *_Fragment, uint64_t _Offset,
00712                MCAssembler *A = 0);
00713 
00714   /// @name Accessors
00715   /// @{
00716 
00717   const MCSymbol &getSymbol() const { return *Symbol; }
00718 
00719   MCFragment *getFragment() const { return Fragment; }
00720   void setFragment(MCFragment *Value) { Fragment = Value; }
00721 
00722   uint64_t getOffset() const { return Offset; }
00723   void setOffset(uint64_t Value) { Offset = Value; }
00724 
00725   /// @}
00726   /// @name Symbol Attributes
00727   /// @{
00728 
00729   bool isExternal() const { return IsExternal; }
00730   void setExternal(bool Value) { IsExternal = Value; }
00731 
00732   bool isPrivateExtern() const { return IsPrivateExtern; }
00733   void setPrivateExtern(bool Value) { IsPrivateExtern = Value; }
00734 
00735   /// isCommon - Is this a 'common' symbol.
00736   bool isCommon() const { return CommonSize != 0; }
00737 
00738   /// setCommon - Mark this symbol as being 'common'.
00739   ///
00740   /// \param Size - The size of the symbol.
00741   /// \param Align - The alignment of the symbol.
00742   void setCommon(uint64_t Size, unsigned Align) {
00743     CommonSize = Size;
00744     CommonAlign = Align;
00745   }
00746 
00747   /// getCommonSize - Return the size of a 'common' symbol.
00748   uint64_t getCommonSize() const {
00749     assert(isCommon() && "Not a 'common' symbol!");
00750     return CommonSize;
00751   }
00752 
00753   void setSize(const MCExpr *SS) {
00754     SymbolSize = SS;
00755   }
00756 
00757   const MCExpr *getSize() const {
00758     return SymbolSize;
00759   }
00760 
00761 
00762   /// getCommonAlignment - Return the alignment of a 'common' symbol.
00763   unsigned getCommonAlignment() const {
00764     assert(isCommon() && "Not a 'common' symbol!");
00765     return CommonAlign;
00766   }
00767 
00768   /// getFlags - Get the (implementation defined) symbol flags.
00769   uint32_t getFlags() const { return Flags; }
00770 
00771   /// setFlags - Set the (implementation defined) symbol flags.
00772   void setFlags(uint32_t Value) { Flags = Value; }
00773 
00774   /// modifyFlags - Modify the flags via a mask
00775   void modifyFlags(uint32_t Value, uint32_t Mask) {
00776     Flags = (Flags & ~Mask) | Value;
00777   }
00778 
00779   /// getIndex - Get the (implementation defined) index.
00780   uint64_t getIndex() const { return Index; }
00781 
00782   /// setIndex - Set the (implementation defined) index.
00783   void setIndex(uint64_t Value) { Index = Value; }
00784 
00785   /// @}
00786 
00787   void dump();
00788 };
00789 
00790 // FIXME: This really doesn't belong here. See comments below.
00791 struct IndirectSymbolData {
00792   MCSymbol *Symbol;
00793   MCSectionData *SectionData;
00794 };
00795 
00796 // FIXME: Ditto this. Purely so the Streamer and the ObjectWriter can talk
00797 // to one another.
00798 struct DataRegionData {
00799   // This enum should be kept in sync w/ the mach-o definition in
00800   // llvm/Object/MachOFormat.h.
00801   enum KindTy { Data = 1, JumpTable8, JumpTable16, JumpTable32 } Kind;
00802   MCSymbol *Start;
00803   MCSymbol *End;
00804 };
00805 
00806 class MCAssembler {
00807   friend class MCAsmLayout;
00808 
00809 public:
00810   typedef iplist<MCSectionData> SectionDataListType;
00811   typedef iplist<MCSymbolData> SymbolDataListType;
00812 
00813   typedef SectionDataListType::const_iterator const_iterator;
00814   typedef SectionDataListType::iterator iterator;
00815 
00816   typedef SymbolDataListType::const_iterator const_symbol_iterator;
00817   typedef SymbolDataListType::iterator symbol_iterator;
00818 
00819   typedef std::vector<IndirectSymbolData>::const_iterator
00820     const_indirect_symbol_iterator;
00821   typedef std::vector<IndirectSymbolData>::iterator indirect_symbol_iterator;
00822 
00823   typedef std::vector<DataRegionData>::const_iterator
00824     const_data_region_iterator;
00825   typedef std::vector<DataRegionData>::iterator data_region_iterator;
00826 
00827 private:
00828   MCAssembler(const MCAssembler&) LLVM_DELETED_FUNCTION;
00829   void operator=(const MCAssembler&) LLVM_DELETED_FUNCTION;
00830 
00831   MCContext &Context;
00832 
00833   MCAsmBackend &Backend;
00834 
00835   MCCodeEmitter &Emitter;
00836 
00837   MCObjectWriter &Writer;
00838 
00839   raw_ostream &OS;
00840 
00841   iplist<MCSectionData> Sections;
00842 
00843   iplist<MCSymbolData> Symbols;
00844 
00845   /// The map of sections to their associated assembler backend data.
00846   //
00847   // FIXME: Avoid this indirection?
00848   DenseMap<const MCSection*, MCSectionData*> SectionMap;
00849 
00850   /// The map of symbols to their associated assembler backend data.
00851   //
00852   // FIXME: Avoid this indirection?
00853   DenseMap<const MCSymbol*, MCSymbolData*> SymbolMap;
00854 
00855   std::vector<IndirectSymbolData> IndirectSymbols;
00856 
00857   std::vector<DataRegionData> DataRegions;
00858 
00859   /// The list of linker options to propagate into the object file.
00860   std::vector<std::vector<std::string> > LinkerOptions;
00861 
00862   /// The set of function symbols for which a .thumb_func directive has
00863   /// been seen.
00864   //
00865   // FIXME: We really would like this in target specific code rather than
00866   // here. Maybe when the relocation stuff moves to target specific,
00867   // this can go with it? The streamer would need some target specific
00868   // refactoring too.
00869   SmallPtrSet<const MCSymbol*, 64> ThumbFuncs;
00870 
00871   /// \brief The bundle alignment size currently set in the assembler.
00872   ///
00873   /// By default it's 0, which means bundling is disabled.
00874   unsigned BundleAlignSize;
00875 
00876   unsigned RelaxAll : 1;
00877   unsigned NoExecStack : 1;
00878   unsigned SubsectionsViaSymbols : 1;
00879 
00880   /// ELF specific e_header flags
00881   // It would be good if there were an MCELFAssembler class to hold this.
00882   // ELF header flags are used both by the integrated and standalone assemblers.
00883   // Access to the flags is necessary in cases where assembler directives affect
00884   // which flags to be set.
00885   unsigned ELFHeaderEFlags;
00886 private:
00887   /// Evaluate a fixup to a relocatable expression and the value which should be
00888   /// placed into the fixup.
00889   ///
00890   /// \param Layout The layout to use for evaluation.
00891   /// \param Fixup The fixup to evaluate.
00892   /// \param DF The fragment the fixup is inside.
00893   /// \param Target [out] On return, the relocatable expression the fixup
00894   /// evaluates to.
00895   /// \param Value [out] On return, the value of the fixup as currently laid
00896   /// out.
00897   /// \return Whether the fixup value was fully resolved. This is true if the
00898   /// \p Value result is fixed, otherwise the value may change due to
00899   /// relocation.
00900   bool evaluateFixup(const MCAsmLayout &Layout,
00901                      const MCFixup &Fixup, const MCFragment *DF,
00902                      MCValue &Target, uint64_t &Value) const;
00903 
00904   /// Check whether a fixup can be satisfied, or whether it needs to be relaxed
00905   /// (increased in size, in order to hold its value correctly).
00906   bool fixupNeedsRelaxation(const MCFixup &Fixup, const MCRelaxableFragment *DF,
00907                             const MCAsmLayout &Layout) const;
00908 
00909   /// Check whether the given fragment needs relaxation.
00910   bool fragmentNeedsRelaxation(const MCRelaxableFragment *IF,
00911                                const MCAsmLayout &Layout) const;
00912 
00913   /// \brief Perform one layout iteration and return true if any offsets
00914   /// were adjusted.
00915   bool layoutOnce(MCAsmLayout &Layout);
00916 
00917   /// \brief Perform one layout iteration of the given section and return true
00918   /// if any offsets were adjusted.
00919   bool layoutSectionOnce(MCAsmLayout &Layout, MCSectionData &SD);
00920 
00921   bool relaxInstruction(MCAsmLayout &Layout, MCRelaxableFragment &IF);
00922 
00923   bool relaxLEB(MCAsmLayout &Layout, MCLEBFragment &IF);
00924 
00925   bool relaxDwarfLineAddr(MCAsmLayout &Layout, MCDwarfLineAddrFragment &DF);
00926   bool relaxDwarfCallFrameFragment(MCAsmLayout &Layout,
00927                                    MCDwarfCallFrameFragment &DF);
00928 
00929   /// finishLayout - Finalize a layout, including fragment lowering.
00930   void finishLayout(MCAsmLayout &Layout);
00931 
00932   uint64_t handleFixup(const MCAsmLayout &Layout,
00933                        MCFragment &F, const MCFixup &Fixup);
00934 
00935 public:
00936   /// Compute the effective fragment size assuming it is laid out at the given
00937   /// \p SectionAddress and \p FragmentOffset.
00938   uint64_t computeFragmentSize(const MCAsmLayout &Layout,
00939                                const MCFragment &F) const;
00940 
00941   /// Find the symbol which defines the atom containing the given symbol, or
00942   /// null if there is no such symbol.
00943   const MCSymbolData *getAtom(const MCSymbolData *Symbol) const;
00944 
00945   /// Check whether a particular symbol is visible to the linker and is required
00946   /// in the symbol table, or whether it can be discarded by the assembler. This
00947   /// also effects whether the assembler treats the label as potentially
00948   /// defining a separate atom.
00949   bool isSymbolLinkerVisible(const MCSymbol &SD) const;
00950 
00951   /// Emit the section contents using the given object writer.
00952   void writeSectionData(const MCSectionData *Section,
00953                         const MCAsmLayout &Layout) const;
00954 
00955   /// Check whether a given symbol has been flagged with .thumb_func.
00956   bool isThumbFunc(const MCSymbol *Func) const {
00957     return ThumbFuncs.count(Func);
00958   }
00959 
00960   /// Flag a function symbol as the target of a .thumb_func directive.
00961   void setIsThumbFunc(const MCSymbol *Func) { ThumbFuncs.insert(Func); }
00962 
00963   /// ELF e_header flags
00964   unsigned getELFHeaderEFlags() const {return ELFHeaderEFlags;}
00965   void setELFHeaderEFlags(unsigned Flags) { ELFHeaderEFlags = Flags;}
00966 
00967 public:
00968   /// Construct a new assembler instance.
00969   ///
00970   /// \param OS The stream to output to.
00971   //
00972   // FIXME: How are we going to parameterize this? Two obvious options are stay
00973   // concrete and require clients to pass in a target like object. The other
00974   // option is to make this abstract, and have targets provide concrete
00975   // implementations as we do with AsmParser.
00976   MCAssembler(MCContext &Context_, MCAsmBackend &Backend_,
00977               MCCodeEmitter &Emitter_, MCObjectWriter &Writer_,
00978               raw_ostream &OS);
00979   ~MCAssembler();
00980 
00981   /// Reuse an assembler instance
00982   ///
00983   void reset();
00984 
00985   MCContext &getContext() const { return Context; }
00986 
00987   MCAsmBackend &getBackend() const { return Backend; }
00988 
00989   MCCodeEmitter &getEmitter() const { return Emitter; }
00990 
00991   MCObjectWriter &getWriter() const { return Writer; }
00992 
00993   /// Finish - Do final processing and write the object to the output stream.
00994   /// \p Writer is used for custom object writer (as the MCJIT does),
00995   /// if not specified it is automatically created from backend.
00996   void Finish();
00997 
00998   // FIXME: This does not belong here.
00999   bool getSubsectionsViaSymbols() const {
01000     return SubsectionsViaSymbols;
01001   }
01002   void setSubsectionsViaSymbols(bool Value) {
01003     SubsectionsViaSymbols = Value;
01004   }
01005 
01006   bool getRelaxAll() const { return RelaxAll; }
01007   void setRelaxAll(bool Value) { RelaxAll = Value; }
01008 
01009   bool getNoExecStack() const { return NoExecStack; }
01010   void setNoExecStack(bool Value) { NoExecStack = Value; }
01011 
01012   bool isBundlingEnabled() const {
01013     return BundleAlignSize != 0;
01014   }
01015 
01016   unsigned getBundleAlignSize() const {
01017     return BundleAlignSize;
01018   }
01019 
01020   void setBundleAlignSize(unsigned Size) {
01021     assert((Size == 0 || !(Size & (Size - 1))) && 
01022            "Expect a power-of-two bundle align size");
01023     BundleAlignSize = Size;
01024   }
01025 
01026   /// @name Section List Access
01027   /// @{
01028 
01029   const SectionDataListType &getSectionList() const { return Sections; }
01030   SectionDataListType &getSectionList() { return Sections; }
01031 
01032   iterator begin() { return Sections.begin(); }
01033   const_iterator begin() const { return Sections.begin(); }
01034 
01035   iterator end() { return Sections.end(); }
01036   const_iterator end() const { return Sections.end(); }
01037 
01038   size_t size() const { return Sections.size(); }
01039 
01040   /// @}
01041   /// @name Symbol List Access
01042   /// @{
01043 
01044   const SymbolDataListType &getSymbolList() const { return Symbols; }
01045   SymbolDataListType &getSymbolList() { return Symbols; }
01046 
01047   symbol_iterator symbol_begin() { return Symbols.begin(); }
01048   const_symbol_iterator symbol_begin() const { return Symbols.begin(); }
01049 
01050   symbol_iterator symbol_end() { return Symbols.end(); }
01051   const_symbol_iterator symbol_end() const { return Symbols.end(); }
01052 
01053   size_t symbol_size() const { return Symbols.size(); }
01054 
01055   /// @}
01056   /// @name Indirect Symbol List Access
01057   /// @{
01058 
01059   // FIXME: This is a total hack, this should not be here. Once things are
01060   // factored so that the streamer has direct access to the .o writer, it can
01061   // disappear.
01062   std::vector<IndirectSymbolData> &getIndirectSymbols() {
01063     return IndirectSymbols;
01064   }
01065 
01066   indirect_symbol_iterator indirect_symbol_begin() {
01067     return IndirectSymbols.begin();
01068   }
01069   const_indirect_symbol_iterator indirect_symbol_begin() const {
01070     return IndirectSymbols.begin();
01071   }
01072 
01073   indirect_symbol_iterator indirect_symbol_end() {
01074     return IndirectSymbols.end();
01075   }
01076   const_indirect_symbol_iterator indirect_symbol_end() const {
01077     return IndirectSymbols.end();
01078   }
01079 
01080   size_t indirect_symbol_size() const { return IndirectSymbols.size(); }
01081 
01082   /// @}
01083   /// @name Linker Option List Access
01084   /// @{
01085 
01086   std::vector<std::vector<std::string> > &getLinkerOptions() {
01087     return LinkerOptions;
01088   }
01089 
01090   /// @}
01091   /// @name Data Region List Access
01092   /// @{
01093 
01094   // FIXME: This is a total hack, this should not be here. Once things are
01095   // factored so that the streamer has direct access to the .o writer, it can
01096   // disappear.
01097   std::vector<DataRegionData> &getDataRegions() {
01098     return DataRegions;
01099   }
01100 
01101   data_region_iterator data_region_begin() {
01102     return DataRegions.begin();
01103   }
01104   const_data_region_iterator data_region_begin() const {
01105     return DataRegions.begin();
01106   }
01107 
01108   data_region_iterator data_region_end() {
01109     return DataRegions.end();
01110   }
01111   const_data_region_iterator data_region_end() const {
01112     return DataRegions.end();
01113   }
01114 
01115   size_t data_region_size() const { return DataRegions.size(); }
01116 
01117   /// @}
01118   /// @name Backend Data Access
01119   /// @{
01120 
01121   MCSectionData &getSectionData(const MCSection &Section) const {
01122     MCSectionData *Entry = SectionMap.lookup(&Section);
01123     assert(Entry && "Missing section data!");
01124     return *Entry;
01125   }
01126 
01127   MCSectionData &getOrCreateSectionData(const MCSection &Section,
01128                                         bool *Created = 0) {
01129     MCSectionData *&Entry = SectionMap[&Section];
01130 
01131     if (Created) *Created = !Entry;
01132     if (!Entry)
01133       Entry = new MCSectionData(Section, this);
01134 
01135     return *Entry;
01136   }
01137 
01138   MCSymbolData &getSymbolData(const MCSymbol &Symbol) const {
01139     MCSymbolData *Entry = SymbolMap.lookup(&Symbol);
01140     assert(Entry && "Missing symbol data!");
01141     return *Entry;
01142   }
01143 
01144   MCSymbolData &getOrCreateSymbolData(const MCSymbol &Symbol,
01145                                       bool *Created = 0) {
01146     MCSymbolData *&Entry = SymbolMap[&Symbol];
01147 
01148     if (Created) *Created = !Entry;
01149     if (!Entry)
01150       Entry = new MCSymbolData(Symbol, 0, 0, this);
01151 
01152     return *Entry;
01153   }
01154 
01155   /// @}
01156 
01157   void dump();
01158 };
01159 
01160 } // end namespace llvm
01161 
01162 #endif