Home | History | Annotate | Download | only in MC
      1 //===- MCFragment.h - Fragment type hierarchy -------------------*- 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_MCFRAGMENT_H
     11 #define LLVM_MC_MCFRAGMENT_H
     12 
     13 #include "llvm/ADT/SmallString.h"
     14 #include "llvm/ADT/ilist.h"
     15 #include "llvm/ADT/ilist_node.h"
     16 #include "llvm/ADT/iterator.h"
     17 #include "llvm/MC/MCFixup.h"
     18 #include "llvm/MC/MCInst.h"
     19 
     20 namespace llvm {
     21 class MCSection;
     22 class MCSymbol;
     23 class MCSubtargetInfo;
     24 
     25 class MCFragment : public ilist_node_with_parent<MCFragment, MCSection> {
     26   friend class MCAsmLayout;
     27 
     28   MCFragment(const MCFragment &) = delete;
     29   void operator=(const MCFragment &) = delete;
     30 
     31 public:
     32   enum FragmentType : uint8_t {
     33     FT_Align,
     34     FT_Data,
     35     FT_CompactEncodedInst,
     36     FT_Fill,
     37     FT_Relaxable,
     38     FT_Org,
     39     FT_Dwarf,
     40     FT_DwarfFrame,
     41     FT_LEB,
     42     FT_SafeSEH,
     43     FT_CVInlineLines,
     44     FT_CVDefRange,
     45     FT_Dummy
     46   };
     47 
     48 private:
     49   FragmentType Kind;
     50 
     51 protected:
     52   bool HasInstructions;
     53 
     54 private:
     55   /// \brief Should this fragment be aligned to the end of a bundle?
     56   bool AlignToBundleEnd;
     57 
     58   uint8_t BundlePadding;
     59 
     60   /// LayoutOrder - The layout order of this fragment.
     61   unsigned LayoutOrder;
     62 
     63   /// The data for the section this fragment is in.
     64   MCSection *Parent;
     65 
     66   /// Atom - The atom this fragment is in, as represented by it's defining
     67   /// symbol.
     68   const MCSymbol *Atom;
     69 
     70   /// \name Assembler Backend Data
     71   /// @{
     72   //
     73   // FIXME: This could all be kept private to the assembler implementation.
     74 
     75   /// Offset - The offset of this fragment in its section. This is ~0 until
     76   /// initialized.
     77   uint64_t Offset;
     78 
     79   /// @}
     80 
     81 protected:
     82   MCFragment(FragmentType Kind, bool HasInstructions,
     83              uint8_t BundlePadding, MCSection *Parent = nullptr);
     84 
     85   ~MCFragment();
     86 private:
     87 
     88   // This is a friend so that the sentinal can be created.
     89   friend struct ilist_sentinel_traits<MCFragment>;
     90   MCFragment();
     91 
     92 public:
     93   /// Destroys the current fragment.
     94   ///
     95   /// This must be used instead of delete as MCFragment is non-virtual.
     96   /// This method will dispatch to the appropriate subclass.
     97   void destroy();
     98 
     99   FragmentType getKind() const { return Kind; }
    100 
    101   MCSection *getParent() const { return Parent; }
    102   void setParent(MCSection *Value) { Parent = Value; }
    103 
    104   const MCSymbol *getAtom() const { return Atom; }
    105   void setAtom(const MCSymbol *Value) { Atom = Value; }
    106 
    107   unsigned getLayoutOrder() const { return LayoutOrder; }
    108   void setLayoutOrder(unsigned Value) { LayoutOrder = Value; }
    109 
    110   /// \brief Does this fragment have instructions emitted into it? By default
    111   /// this is false, but specific fragment types may set it to true.
    112   bool hasInstructions() const { return HasInstructions; }
    113 
    114   /// \brief Should this fragment be placed at the end of an aligned bundle?
    115   bool alignToBundleEnd() const { return AlignToBundleEnd; }
    116   void setAlignToBundleEnd(bool V) { AlignToBundleEnd = V; }
    117 
    118   /// \brief Get the padding size that must be inserted before this fragment.
    119   /// Used for bundling. By default, no padding is inserted.
    120   /// Note that padding size is restricted to 8 bits. This is an optimization
    121   /// to reduce the amount of space used for each fragment. In practice, larger
    122   /// padding should never be required.
    123   uint8_t getBundlePadding() const { return BundlePadding; }
    124 
    125   /// \brief Set the padding size for this fragment. By default it's a no-op,
    126   /// and only some fragments have a meaningful implementation.
    127   void setBundlePadding(uint8_t N) { BundlePadding = N; }
    128 
    129   /// \brief Return true if given frgment has FT_Dummy type.
    130   bool isDummy() const { return Kind == FT_Dummy; }
    131 
    132   void dump();
    133 };
    134 
    135 class MCDummyFragment : public MCFragment {
    136 public:
    137   explicit MCDummyFragment(MCSection *Sec)
    138       : MCFragment(FT_Dummy, false, 0, Sec){};
    139   static bool classof(const MCFragment *F) { return F->getKind() == FT_Dummy; }
    140 };
    141 
    142 /// Interface implemented by fragments that contain encoded instructions and/or
    143 /// data.
    144 ///
    145 class MCEncodedFragment : public MCFragment {
    146 protected:
    147   MCEncodedFragment(MCFragment::FragmentType FType, bool HasInstructions,
    148                     MCSection *Sec)
    149       : MCFragment(FType, HasInstructions, 0, Sec) {}
    150 
    151 public:
    152   static bool classof(const MCFragment *F) {
    153     MCFragment::FragmentType Kind = F->getKind();
    154     switch (Kind) {
    155     default:
    156       return false;
    157     case MCFragment::FT_Relaxable:
    158     case MCFragment::FT_CompactEncodedInst:
    159     case MCFragment::FT_Data:
    160       return true;
    161     }
    162   }
    163 };
    164 
    165 /// Interface implemented by fragments that contain encoded instructions and/or
    166 /// data.
    167 ///
    168 template<unsigned ContentsSize>
    169 class MCEncodedFragmentWithContents : public MCEncodedFragment {
    170   SmallVector<char, ContentsSize> Contents;
    171 
    172 protected:
    173   MCEncodedFragmentWithContents(MCFragment::FragmentType FType,
    174                                 bool HasInstructions,
    175                                 MCSection *Sec)
    176       : MCEncodedFragment(FType, HasInstructions, Sec) {}
    177 
    178 public:
    179   SmallVectorImpl<char> &getContents() { return Contents; }
    180   const SmallVectorImpl<char> &getContents() const { return Contents; }
    181 };
    182 
    183 /// Interface implemented by fragments that contain encoded instructions and/or
    184 /// data and also have fixups registered.
    185 ///
    186 template<unsigned ContentsSize, unsigned FixupsSize>
    187 class MCEncodedFragmentWithFixups :
    188   public MCEncodedFragmentWithContents<ContentsSize> {
    189 
    190   /// Fixups - The list of fixups in this fragment.
    191   SmallVector<MCFixup, FixupsSize> Fixups;
    192 
    193 protected:
    194   MCEncodedFragmentWithFixups(MCFragment::FragmentType FType,
    195                               bool HasInstructions,
    196                               MCSection *Sec)
    197       : MCEncodedFragmentWithContents<ContentsSize>(FType, HasInstructions,
    198                                                     Sec) {}
    199 
    200 public:
    201   typedef SmallVectorImpl<MCFixup>::const_iterator const_fixup_iterator;
    202   typedef SmallVectorImpl<MCFixup>::iterator fixup_iterator;
    203 
    204   SmallVectorImpl<MCFixup> &getFixups() { return Fixups; }
    205   const SmallVectorImpl<MCFixup> &getFixups() const { return Fixups; }
    206 
    207   fixup_iterator fixup_begin() { return Fixups.begin(); }
    208   const_fixup_iterator fixup_begin() const { return Fixups.begin(); }
    209 
    210   fixup_iterator fixup_end() { return Fixups.end(); }
    211   const_fixup_iterator fixup_end() const { return Fixups.end(); }
    212 
    213   static bool classof(const MCFragment *F) {
    214     MCFragment::FragmentType Kind = F->getKind();
    215     return Kind == MCFragment::FT_Relaxable || Kind == MCFragment::FT_Data ||
    216            Kind == MCFragment::FT_CVDefRange;
    217   }
    218 };
    219 
    220 /// Fragment for data and encoded instructions.
    221 ///
    222 class MCDataFragment : public MCEncodedFragmentWithFixups<32, 4> {
    223 public:
    224   MCDataFragment(MCSection *Sec = nullptr)
    225       : MCEncodedFragmentWithFixups<32, 4>(FT_Data, false, Sec) {}
    226 
    227   void setHasInstructions(bool V) { HasInstructions = V; }
    228 
    229   static bool classof(const MCFragment *F) {
    230     return F->getKind() == MCFragment::FT_Data;
    231   }
    232 };
    233 
    234 /// This is a compact (memory-size-wise) fragment for holding an encoded
    235 /// instruction (non-relaxable) that has no fixups registered. When applicable,
    236 /// it can be used instead of MCDataFragment and lead to lower memory
    237 /// consumption.
    238 ///
    239 class MCCompactEncodedInstFragment : public MCEncodedFragmentWithContents<4> {
    240 public:
    241   MCCompactEncodedInstFragment(MCSection *Sec = nullptr)
    242       : MCEncodedFragmentWithContents(FT_CompactEncodedInst, true, Sec) {
    243   }
    244 
    245   static bool classof(const MCFragment *F) {
    246     return F->getKind() == MCFragment::FT_CompactEncodedInst;
    247   }
    248 };
    249 
    250 /// A relaxable fragment holds on to its MCInst, since it may need to be
    251 /// relaxed during the assembler layout and relaxation stage.
    252 ///
    253 class MCRelaxableFragment : public MCEncodedFragmentWithFixups<8, 1> {
    254 
    255   /// Inst - The instruction this is a fragment for.
    256   MCInst Inst;
    257 
    258   /// STI - The MCSubtargetInfo in effect when the instruction was encoded.
    259   const MCSubtargetInfo &STI;
    260 
    261 public:
    262   MCRelaxableFragment(const MCInst &Inst, const MCSubtargetInfo &STI,
    263                       MCSection *Sec = nullptr)
    264       : MCEncodedFragmentWithFixups(FT_Relaxable, true, Sec),
    265         Inst(Inst), STI(STI) {}
    266 
    267   const MCInst &getInst() const { return Inst; }
    268   void setInst(const MCInst &Value) { Inst = Value; }
    269 
    270   const MCSubtargetInfo &getSubtargetInfo() { return STI; }
    271 
    272   static bool classof(const MCFragment *F) {
    273     return F->getKind() == MCFragment::FT_Relaxable;
    274   }
    275 };
    276 
    277 class MCAlignFragment : public MCFragment {
    278 
    279   /// Alignment - The alignment to ensure, in bytes.
    280   unsigned Alignment;
    281 
    282   /// EmitNops - Flag to indicate that (optimal) NOPs should be emitted instead
    283   /// of using the provided value. The exact interpretation of this flag is
    284   /// target dependent.
    285   bool EmitNops : 1;
    286 
    287   /// Value - Value to use for filling padding bytes.
    288   int64_t Value;
    289 
    290   /// ValueSize - The size of the integer (in bytes) of \p Value.
    291   unsigned ValueSize;
    292 
    293   /// MaxBytesToEmit - The maximum number of bytes to emit; if the alignment
    294   /// cannot be satisfied in this width then this fragment is ignored.
    295   unsigned MaxBytesToEmit;
    296 
    297 public:
    298   MCAlignFragment(unsigned Alignment, int64_t Value, unsigned ValueSize,
    299                   unsigned MaxBytesToEmit, MCSection *Sec = nullptr)
    300       : MCFragment(FT_Align, false, 0, Sec), Alignment(Alignment),
    301         EmitNops(false), Value(Value),
    302         ValueSize(ValueSize), MaxBytesToEmit(MaxBytesToEmit) {}
    303 
    304   /// \name Accessors
    305   /// @{
    306 
    307   unsigned getAlignment() const { return Alignment; }
    308 
    309   int64_t getValue() const { return Value; }
    310 
    311   unsigned getValueSize() const { return ValueSize; }
    312 
    313   unsigned getMaxBytesToEmit() const { return MaxBytesToEmit; }
    314 
    315   bool hasEmitNops() const { return EmitNops; }
    316   void setEmitNops(bool Value) { EmitNops = Value; }
    317 
    318   /// @}
    319 
    320   static bool classof(const MCFragment *F) {
    321     return F->getKind() == MCFragment::FT_Align;
    322   }
    323 };
    324 
    325 class MCFillFragment : public MCFragment {
    326 
    327   /// Value to use for filling bytes.
    328   uint8_t Value;
    329 
    330   /// The number of bytes to insert.
    331   uint64_t Size;
    332 
    333 public:
    334   MCFillFragment(uint8_t Value, uint64_t Size, MCSection *Sec = nullptr)
    335       : MCFragment(FT_Fill, false, 0, Sec), Value(Value), Size(Size) {}
    336 
    337   uint8_t getValue() const { return Value; }
    338   uint64_t getSize() const { return Size; }
    339 
    340   static bool classof(const MCFragment *F) {
    341     return F->getKind() == MCFragment::FT_Fill;
    342   }
    343 };
    344 
    345 class MCOrgFragment : public MCFragment {
    346 
    347   /// Offset - The offset this fragment should start at.
    348   const MCExpr *Offset;
    349 
    350   /// Value - Value to use for filling bytes.
    351   int8_t Value;
    352 
    353 public:
    354   MCOrgFragment(const MCExpr &Offset, int8_t Value, MCSection *Sec = nullptr)
    355       : MCFragment(FT_Org, false, 0, Sec), Offset(&Offset), Value(Value) {}
    356 
    357   /// \name Accessors
    358   /// @{
    359 
    360   const MCExpr &getOffset() const { return *Offset; }
    361 
    362   uint8_t getValue() const { return Value; }
    363 
    364   /// @}
    365 
    366   static bool classof(const MCFragment *F) {
    367     return F->getKind() == MCFragment::FT_Org;
    368   }
    369 };
    370 
    371 class MCLEBFragment : public MCFragment {
    372 
    373   /// Value - The value this fragment should contain.
    374   const MCExpr *Value;
    375 
    376   /// IsSigned - True if this is a sleb128, false if uleb128.
    377   bool IsSigned;
    378 
    379   SmallString<8> Contents;
    380 
    381 public:
    382   MCLEBFragment(const MCExpr &Value_, bool IsSigned_, MCSection *Sec = nullptr)
    383       : MCFragment(FT_LEB, false, 0, Sec), Value(&Value_), IsSigned(IsSigned_) {
    384     Contents.push_back(0);
    385   }
    386 
    387   /// \name Accessors
    388   /// @{
    389 
    390   const MCExpr &getValue() const { return *Value; }
    391 
    392   bool isSigned() const { return IsSigned; }
    393 
    394   SmallString<8> &getContents() { return Contents; }
    395   const SmallString<8> &getContents() const { return Contents; }
    396 
    397   /// @}
    398 
    399   static bool classof(const MCFragment *F) {
    400     return F->getKind() == MCFragment::FT_LEB;
    401   }
    402 };
    403 
    404 class MCDwarfLineAddrFragment : public MCFragment {
    405 
    406   /// LineDelta - the value of the difference between the two line numbers
    407   /// between two .loc dwarf directives.
    408   int64_t LineDelta;
    409 
    410   /// AddrDelta - The expression for the difference of the two symbols that
    411   /// make up the address delta between two .loc dwarf directives.
    412   const MCExpr *AddrDelta;
    413 
    414   SmallString<8> Contents;
    415 
    416 public:
    417   MCDwarfLineAddrFragment(int64_t LineDelta, const MCExpr &AddrDelta,
    418                           MCSection *Sec = nullptr)
    419       : MCFragment(FT_Dwarf, false, 0, Sec), LineDelta(LineDelta),
    420         AddrDelta(&AddrDelta) {
    421     Contents.push_back(0);
    422   }
    423 
    424   /// \name Accessors
    425   /// @{
    426 
    427   int64_t getLineDelta() const { return LineDelta; }
    428 
    429   const MCExpr &getAddrDelta() const { return *AddrDelta; }
    430 
    431   SmallString<8> &getContents() { return Contents; }
    432   const SmallString<8> &getContents() const { return Contents; }
    433 
    434   /// @}
    435 
    436   static bool classof(const MCFragment *F) {
    437     return F->getKind() == MCFragment::FT_Dwarf;
    438   }
    439 };
    440 
    441 class MCDwarfCallFrameFragment : public MCFragment {
    442 
    443   /// AddrDelta - The expression for the difference of the two symbols that
    444   /// make up the address delta between two .cfi_* dwarf directives.
    445   const MCExpr *AddrDelta;
    446 
    447   SmallString<8> Contents;
    448 
    449 public:
    450   MCDwarfCallFrameFragment(const MCExpr &AddrDelta, MCSection *Sec = nullptr)
    451       : MCFragment(FT_DwarfFrame, false, 0, Sec), AddrDelta(&AddrDelta) {
    452     Contents.push_back(0);
    453   }
    454 
    455   /// \name Accessors
    456   /// @{
    457 
    458   const MCExpr &getAddrDelta() const { return *AddrDelta; }
    459 
    460   SmallString<8> &getContents() { return Contents; }
    461   const SmallString<8> &getContents() const { return Contents; }
    462 
    463   /// @}
    464 
    465   static bool classof(const MCFragment *F) {
    466     return F->getKind() == MCFragment::FT_DwarfFrame;
    467   }
    468 };
    469 
    470 class MCSafeSEHFragment : public MCFragment {
    471   const MCSymbol *Sym;
    472 
    473 public:
    474   MCSafeSEHFragment(const MCSymbol *Sym, MCSection *Sec = nullptr)
    475       : MCFragment(FT_SafeSEH, false, 0, Sec), Sym(Sym) {}
    476 
    477   /// \name Accessors
    478   /// @{
    479 
    480   const MCSymbol *getSymbol() { return Sym; }
    481   const MCSymbol *getSymbol() const { return Sym; }
    482 
    483   /// @}
    484 
    485   static bool classof(const MCFragment *F) {
    486     return F->getKind() == MCFragment::FT_SafeSEH;
    487   }
    488 };
    489 
    490 /// Fragment representing the binary annotations produced by the
    491 /// .cv_inline_linetable directive.
    492 class MCCVInlineLineTableFragment : public MCFragment {
    493   unsigned SiteFuncId;
    494   unsigned StartFileId;
    495   unsigned StartLineNum;
    496   const MCSymbol *FnStartSym;
    497   const MCSymbol *FnEndSym;
    498   SmallVector<unsigned, 3> SecondaryFuncs;
    499   SmallString<8> Contents;
    500 
    501   /// CodeViewContext has the real knowledge about this format, so let it access
    502   /// our members.
    503   friend class CodeViewContext;
    504 
    505 public:
    506   MCCVInlineLineTableFragment(unsigned SiteFuncId, unsigned StartFileId,
    507                               unsigned StartLineNum, const MCSymbol *FnStartSym,
    508                               const MCSymbol *FnEndSym,
    509                               ArrayRef<unsigned> SecondaryFuncs,
    510                               MCSection *Sec = nullptr)
    511       : MCFragment(FT_CVInlineLines, false, 0, Sec), SiteFuncId(SiteFuncId),
    512         StartFileId(StartFileId), StartLineNum(StartLineNum),
    513         FnStartSym(FnStartSym), FnEndSym(FnEndSym),
    514         SecondaryFuncs(SecondaryFuncs.begin(), SecondaryFuncs.end()) {}
    515 
    516   /// \name Accessors
    517   /// @{
    518 
    519   const MCSymbol *getFnStartSym() const { return FnStartSym; }
    520   const MCSymbol *getFnEndSym() const { return FnEndSym; }
    521 
    522   SmallString<8> &getContents() { return Contents; }
    523   const SmallString<8> &getContents() const { return Contents; }
    524 
    525   /// @}
    526 
    527   static bool classof(const MCFragment *F) {
    528     return F->getKind() == MCFragment::FT_CVInlineLines;
    529   }
    530 };
    531 
    532 /// Fragment representing the .cv_def_range directive.
    533 class MCCVDefRangeFragment : public MCEncodedFragmentWithFixups<32, 4> {
    534   SmallVector<std::pair<const MCSymbol *, const MCSymbol *>, 2> Ranges;
    535   SmallString<32> FixedSizePortion;
    536 
    537   /// CodeViewContext has the real knowledge about this format, so let it access
    538   /// our members.
    539   friend class CodeViewContext;
    540 
    541 public:
    542   MCCVDefRangeFragment(
    543       ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
    544       StringRef FixedSizePortion, MCSection *Sec = nullptr)
    545       : MCEncodedFragmentWithFixups<32, 4>(FT_CVDefRange, false, Sec),
    546         Ranges(Ranges.begin(), Ranges.end()),
    547         FixedSizePortion(FixedSizePortion) {}
    548 
    549   /// \name Accessors
    550   /// @{
    551   ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> getRanges() const {
    552     return Ranges;
    553   }
    554 
    555   StringRef getFixedSizePortion() const { return FixedSizePortion; }
    556   /// @}
    557 
    558   static bool classof(const MCFragment *F) {
    559     return F->getKind() == MCFragment::FT_CVDefRange;
    560   }
    561 };
    562 
    563 } // end namespace llvm
    564 
    565 #endif
    566