Home | History | Annotate | Download | only in LD
      1 //===- ELFReader.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 #ifndef MCLD_ELF_READER_INTERFACE_H
     10 #define MCLD_ELF_READER_INTERFACE_H
     11 #ifdef ENABLE_UNITTEST
     12 #include <gtest.h>
     13 #endif
     14 
     15 #include <llvm/ADT/StringRef.h>
     16 #include <llvm/Support/ELF.h>
     17 #include <llvm/Support/Host.h>
     18 #include <llvm/MC/MCAssembler.h>
     19 #include <mcld/MC/MCLDInfo.h>
     20 #include <mcld/MC/MCLDInput.h>
     21 #include <mcld/MC/MCLinker.h>
     22 #include <mcld/MC/MCRegionFragment.h>
     23 #include <mcld/LD/ResolveInfo.h>
     24 #include <mcld/LD/LDContext.h>
     25 #include <mcld/Target/GNULDBackend.h>
     26 #include <mcld/Support/MemoryRegion.h>
     27 
     28 namespace mcld
     29 {
     30 
     31 /** \class ELFReaderIF
     32  *  \brief ELFReaderIF provides common interface for all kind of ELF readers.
     33  */
     34 class ELFReaderIF
     35 {
     36 public:
     37   ELFReaderIF(GNULDBackend& pBackend)
     38     : m_Backend(pBackend)
     39   { }
     40 
     41   virtual ~ELFReaderIF() { }
     42 
     43   /// ELFHeaderSize - return the size of the ELFHeader
     44   virtual size_t getELFHeaderSize() const = 0;
     45 
     46   /// isELF - is this a ELF file
     47   virtual bool isELF(void* pELFHeader) const = 0;
     48 
     49   /// isMyEndian - is this ELF file in the same endian to me?
     50   virtual bool isMyEndian(void* pELFHeader) const = 0;
     51 
     52   /// isMyMachine - is this ELF file generated for the same machine.
     53   virtual bool isMyMachine(void* pELFHeader) const = 0;
     54 
     55   /// fileType - the file type of this file
     56   virtual MCLDFile::Type fileType(void* pELFHeader) const = 0;
     57 
     58   /// target - the target backend
     59   GNULDBackend& target()
     60   { return m_Backend; }
     61 
     62   /// target - the target backend
     63   const GNULDBackend& target() const
     64   { return m_Backend; }
     65 
     66   /// readSectionHeaders - read ELF section header table and create LDSections
     67   virtual bool readSectionHeaders(Input& pInput,
     68                                   MCLinker& pLinker,
     69                                   void* pELFHeader) const = 0;
     70 
     71   /// readRegularSection - read a regular section and create fragments.
     72   virtual bool readRegularSection(Input& pInput,
     73                                   MCLinker& pLinker,
     74                                   LDSection& pSectHdr) const = 0;
     75 
     76   /// readRegularSection - read a target section and create fragments.
     77   virtual bool readTargetSection(Input& pInput,
     78                                  MCLinker& pLinker,
     79                                  LDSection& pSectHdr) = 0;
     80 
     81   /// readSymbols - read ELF symbols and create LDSymbol
     82   virtual bool readSymbols(Input& pInput,
     83                            MCLinker& pLinker,
     84                            const MemoryRegion& pRegion,
     85                            const char* StrTab) const = 0;
     86 
     87   /// readSymbol - read a symbol from the given Input and index in symtab
     88   virtual ResolveInfo* readSymbol(Input& pInput,
     89                                   LDSection& pSymTab,
     90                                   MCLDInfo& pLDInfo,
     91                                   uint32_t pSymIdx) const = 0;
     92 
     93   /// readRela - read ELF rela and create Relocation
     94   virtual bool readRela(Input& pInput,
     95                         MCLinker& pLinker,
     96                         LDSection& pSection,
     97                         const MemoryRegion& pRegion) const = 0;
     98 
     99   /// readRel - read ELF rel and create Relocation
    100   virtual bool readRel(Input& pInput,
    101                        MCLinker& pLinker,
    102                        LDSection& pSection,
    103                        const MemoryRegion& pRegion) const = 0;
    104 protected:
    105   /// LinkInfo - some section needs sh_link and sh_info, remember them.
    106   struct LinkInfo {
    107     LDSection* section;
    108     uint32_t sh_link;
    109     uint32_t sh_info;
    110   };
    111 
    112   typedef std::vector<LinkInfo> LinkInfoList;
    113 
    114 protected:
    115   LDFileFormat::Kind getLDSectionKind(uint32_t pType, const char* pName) const;
    116 
    117   ResolveInfo::Desc getSymDesc(uint16_t pShndx, const Input& pInput) const;
    118 
    119   ResolveInfo::Binding getSymBinding(uint8_t pBinding,
    120                                      uint16_t pShndx,
    121                                      uint8_t pVisibility) const;
    122 
    123   uint64_t getSymValue(uint64_t pValue,
    124                        uint16_t pShndx,
    125                        const Input& pInput) const;
    126 
    127   MCFragmentRef* getSymFragmentRef(Input& pInput,
    128                                    MCLinker& pLinker,
    129                                    uint16_t pShndx,
    130                                    uint32_t pOffset) const;
    131 
    132   ResolveInfo::Visibility getSymVisibility(uint8_t pVis) const;
    133 
    134 private:
    135   GNULDBackend& m_Backend;
    136 };
    137 
    138 /** \class ELFReader
    139  *  \brief ELFReader is a template scaffolding for partial specification.
    140  */
    141 template<size_t BIT, bool LITTLEENDIAN>
    142 class ELFReader
    143 { };
    144 
    145 /** \class ELFReader<32, true>
    146  *  \brief ELFReader<32, true> is a 32-bit, little endian ELFReader.
    147  */
    148 template<>
    149 class ELFReader<32, true> : public ELFReaderIF
    150 {
    151 public:
    152   typedef llvm::ELF::Elf32_Ehdr ELFHeader;
    153   typedef llvm::ELF::Elf32_Shdr SectionHeader;
    154   typedef llvm::ELF::Elf32_Sym  Symbol;
    155   typedef llvm::ELF::Elf32_Rel  Rel;
    156   typedef llvm::ELF::Elf32_Rela Rela;
    157 
    158 public:
    159   inline ELFReader(GNULDBackend& pBackend);
    160 
    161   inline ~ELFReader();
    162 
    163   /// ELFHeaderSize - return the size of the ELFHeader
    164   inline size_t getELFHeaderSize() const
    165   { return sizeof(ELFHeader); }
    166 
    167   /// isELF - is this a ELF file
    168   inline bool isELF(void* pELFHeader) const;
    169 
    170   /// isMyEndian - is this ELF file in the same endian to me?
    171   inline bool isMyEndian(void* pELFHeader) const;
    172 
    173   /// isMyMachine - is this ELF file generated for the same machine.
    174   inline bool isMyMachine(void* pELFHeader) const;
    175 
    176   /// fileType - the file type of this file
    177   inline MCLDFile::Type fileType(void* pELFHeader) const;
    178 
    179   /// readSectionHeaders - read ELF section header table and create LDSections
    180   inline bool readSectionHeaders(Input& pInput,
    181                           MCLinker& pLinker,
    182                           void* pELFHeader) const;
    183 
    184   /// readRegularSection - read a regular section and create fragments.
    185   inline bool readRegularSection(Input& pInput,
    186                                  MCLinker& pLinker,
    187                                  LDSection& pInputSectHdr) const;
    188 
    189   /// readRegularSection - read a target section and create fragments.
    190   inline bool readTargetSection(Input& pInput,
    191                                 MCLinker& pLinker,
    192                                 LDSection& pInputSectHdr);
    193 
    194   /// readSymbols - read ELF symbols and create LDSymbol
    195   inline bool readSymbols(Input& pInput,
    196                           MCLinker& pLinker,
    197                           const MemoryRegion& pRegion,
    198                           const char* StrTab) const;
    199 
    200   /// readSymbol - read a symbol from the given Input and index in symtab
    201   inline ResolveInfo* readSymbol(Input& pInput,
    202                                  LDSection& pSymTab,
    203                                  MCLDInfo& pLDInfo,
    204                                  uint32_t pSymIdx) const;
    205 
    206   /// readRela - read ELF rela and create Relocation
    207   inline bool readRela(Input& pInput,
    208                        MCLinker& pLinker,
    209                        LDSection& pSection,
    210                        const MemoryRegion& pRegion) const;
    211 
    212   /// readRel - read ELF rel and create Relocation
    213   inline bool readRel(Input& pInput,
    214                       MCLinker& pLinker,
    215                       LDSection& pSection,
    216                       const MemoryRegion& pRegion) const;
    217 };
    218 
    219 #include "ELFReader.tcc"
    220 
    221 } // namespace of mcld
    222 
    223 #endif
    224