Home | History | Annotate | Download | only in LD
      1 //===- LDSection.h --------------------------------------------------------===//
      2 //
      3 //                     The MCLinker Project
      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 MCLD_LD_LDSECTION_H
     11 #define MCLD_LD_LDSECTION_H
     12 #ifdef ENABLE_UNITTEST
     13 #include <gtest.h>
     14 #endif
     15 
     16 #include <llvm/MC/MCSection.h>
     17 #include <llvm/MC/MCAssembler.h>
     18 #include <llvm/ADT/StringRef.h>
     19 #include <llvm/Support/DataTypes.h>
     20 #include <mcld/LD/LDFileFormat.h>
     21 #include <string>
     22 
     23 namespace llvm {
     24 
     25 class MCAsmInfo;
     26 class raw_ostream;
     27 
     28 } // namespace of llvm
     29 
     30 namespace mcld {
     31 /** \class LDSection
     32  *  \brief LDSection represents a section header entry. It is a unified
     33  *  abstraction for various file formats.
     34  *
     35  *  LDSection contains both the format-dependent data and LLVM specific data.
     36  *
     37  */
     38 class LDSection : public llvm::MCSection
     39 {
     40 public:
     41   LDSection(const std::string& pName,
     42             LDFileFormat::Kind pKind,
     43             uint32_t pType,
     44             uint32_t pFlag,
     45             uint64_t pSize = 0,
     46             uint64_t pOffset = 0,
     47             uint64_t pAddr = 0);
     48 
     49   /// name - the name of this section.
     50   const std::string& name() const
     51   { return m_Name; }
     52 
     53   /// kind - the kind of this section, such as Text, BSS, GOT, and so on.
     54   /// from LDFileFormat::Kind
     55   LDFileFormat::Kind kind() const
     56   { return m_Kind; }
     57 
     58   /// type - The categorizes the section's contents and semantics. It's
     59   /// different from llvm::SectionKind. Type is format-dependent, but
     60   /// llvm::SectionKind is format independent and is used for bit-code.
     61   ///   In ELF, it is sh_type
     62   ///   In MachO, it's type field of struct section::flags
     63   uint32_t type() const
     64   { return m_Type; }
     65 
     66   /// flag - An integer describes miscellaneous attributes.
     67   ///   In ELF, it is sh_flags.
     68   ///   In MachO, it's attribute field of struct section::flags
     69   uint32_t flag() const
     70   { return m_Flag; }
     71 
     72   /// size - An integer specifying the size in bytes of the virtual memory
     73   /// occupied by this section.
     74   ///   In ELF, if the type() is SHT_NOBITS, this function return zero.
     75   ///   Before layouting, output's LDSection::size() should return zero.
     76   uint64_t size() const
     77   { return m_Size; }
     78 
     79   /// offset - An integer specifying the offset of this section in the file.
     80   ///   Before layouting, output's LDSection::offset() should return zero.
     81   uint64_t offset() const
     82   { return m_Offset; }
     83 
     84   /// addr - An integer specifying the virtual address of this section in the
     85   /// virtual image.
     86   ///   Before layouting, output's LDSection::offset() should return zero.
     87   ///   ELF uses sh_addralign to set alignment constraints. In LLVM, alignment
     88   ///   constraint is set in MCSectionData::setAlignment. addr() contains the
     89   ///   original ELF::sh_addr. Modulo sh_addr by sh_addralign is not necessary.
     90   ///   MachO uses the same scenario.
     91   ///
     92   ///   Because addr() in output is changing during linking, MCLinker does not
     93   ///   store the address of the output here. The address is in Layout
     94   uint64_t addr() const
     95   { return m_Addr; }
     96 
     97   /// align - An integer specifying the align of this section in the file.
     98   ///   Before layouting, output's LDSection::align() should return zero.
     99   uint32_t align() const
    100   { return m_Align; }
    101 
    102   size_t index() const
    103   { return m_Index; }
    104 
    105   /// getLink - return the Link. When a section A needs the other section B
    106   /// during linking or loading, we say B is A's Link section.
    107   /// In ELF, InfoLink section control the ElfNN_Shdr::sh_link and sh_info.
    108   ///
    109   /// @return if the section needs no other sections, return NULL
    110   LDSection* getLink()
    111   { return m_pLink; }
    112 
    113   const LDSection* getLink() const
    114   { return m_pLink; }
    115 
    116   size_t getInfo() const
    117   { return m_Info; }
    118 
    119   void setKind(LDFileFormat::Kind pKind)
    120   { m_Kind = pKind; }
    121 
    122   void setSize(uint64_t size)
    123   { m_Size = size; }
    124 
    125   void setOffset(uint64_t Offset)
    126   { m_Offset = Offset; }
    127 
    128   void setAddr(uint64_t addr)
    129   { m_Addr = addr; }
    130 
    131   void setAlign(uint32_t align)
    132   { m_Align = align; }
    133 
    134   void setFlag(uint32_t flag)
    135   { m_Flag = flag; }
    136 
    137   void setType(uint32_t type)
    138   { m_Type = type; }
    139 
    140   static bool classof(const MCSection *S)
    141   { return S->getVariant() == SV_LDContext; }
    142 
    143   static bool classof(const LDSection *)
    144   { return true; }
    145 
    146   // -----  methods for adapt to llvm::MCSection  ----- //
    147   void PrintSwitchToSection(const llvm::MCAsmInfo &MAI,
    148                             llvm::raw_ostream &OS) const
    149   { }
    150 
    151   bool UseCodeAlign() const
    152   { return true; }
    153 
    154   bool isVirtualSection() const
    155   { return false; }
    156 
    157   llvm::MCSectionData* getSectionData()
    158   { return m_pSectionData; }
    159 
    160   const llvm::MCSectionData* getSectionData() const
    161   { return m_pSectionData; }
    162 
    163   void setSectionData(llvm::MCSectionData* pSD)
    164   { m_pSectionData = pSD; }
    165 
    166   bool hasSectionData() const
    167   { return (NULL != m_pSectionData); }
    168 
    169   /// setLink - set the sections should link with.
    170   /// if pLink is NULL, no Link section is set.
    171   void setLink(LDSection* pLink)
    172   { m_pLink = pLink; }
    173 
    174   void setInfo(size_t pInfo)
    175   { m_Info = pInfo; }
    176 
    177   void setIndex(size_t pIndex)
    178   { m_Index = pIndex; }
    179 
    180 private:
    181   std::string m_Name;
    182   LDFileFormat::Kind m_Kind;
    183   uint32_t m_Type;
    184   uint32_t m_Flag;
    185 
    186   uint64_t m_Size;
    187   uint64_t m_Offset;
    188   uint64_t m_Addr;
    189   uint32_t m_Align;
    190 
    191   size_t m_Info;
    192   LDSection* m_pLink;
    193 
    194   // pointer to MCSectionData.
    195   llvm::MCSectionData* m_pSectionData;
    196 
    197   // the index of the file
    198   size_t m_Index;
    199 
    200 }; // end of LDSection
    201 
    202 } // end namespace mcld
    203 
    204 #endif
    205