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