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_LD_ELFREADER_H
     10 #define MCLD_LD_ELFREADER_H
     11 
     12 #include <llvm/ADT/StringRef.h>
     13 #include <llvm/Support/ELF.h>
     14 #include <llvm/Support/Host.h>
     15 
     16 #include <mcld/LD/ELFReaderIf.h>
     17 #include <mcld/LD/ResolveInfo.h>
     18 #include <mcld/LD/LDSymbol.h>
     19 #include <mcld/Target/GNULDBackend.h>
     20 
     21 namespace mcld {
     22 
     23 //class Module;
     24 class IRBuilder;
     25 class SectionData;
     26 class LDSection;
     27 
     28 /** \class ELFReader
     29  *  \brief ELFReader is a template scaffolding for partial specification.
     30  */
     31 template<size_t BIT, bool LITTLEENDIAN>
     32 class ELFReader
     33 { };
     34 
     35 /** \class ELFReader<32, true>
     36  *  \brief ELFReader<32, true> is a 32-bit, little endian ELFReader.
     37  */
     38 template<>
     39 class ELFReader<32, true> : public ELFReaderIF
     40 {
     41 public:
     42   typedef llvm::ELF::Elf32_Ehdr ELFHeader;
     43   typedef llvm::ELF::Elf32_Shdr SectionHeader;
     44   typedef llvm::ELF::Elf32_Sym  Symbol;
     45   typedef llvm::ELF::Elf32_Rel  Rel;
     46   typedef llvm::ELF::Elf32_Rela Rela;
     47 
     48 public:
     49   ELFReader(GNULDBackend& pBackend);
     50 
     51   ~ELFReader();
     52 
     53   /// ELFHeaderSize - return the size of the ELFHeader
     54   size_t getELFHeaderSize() const
     55   { return sizeof(ELFHeader); }
     56 
     57   /// isELF - is this a ELF file
     58   bool isELF(const void* pELFHeader) const;
     59 
     60   /// isMyEndian - is this ELF file in the same endian to me?
     61   bool isMyEndian(const void* pELFHeader) const;
     62 
     63   /// isMyMachine - is this ELF file generated for the same machine.
     64   bool isMyMachine(const void* pELFHeader) const;
     65 
     66   /// fileType - the file type of this file
     67   Input::Type fileType(const void* pELFHeader) const;
     68 
     69   /// readSectionHeaders - read ELF section header table and create LDSections
     70   bool readSectionHeaders(Input& pInput, const void* pELFHeader) const;
     71 
     72   /// readRegularSection - read a regular section and create fragments.
     73   bool readRegularSection(Input& pInput, SectionData& pSD) const;
     74 
     75   /// readSymbols - read ELF symbols and create LDSymbol
     76   bool readSymbols(Input& pInput,
     77                    IRBuilder& pBuilder,
     78                    llvm::StringRef pRegion,
     79                    const char* StrTab) const;
     80 
     81   /// readSignature - read a symbol from the given Input and index in symtab
     82   /// This is used to get the signature of a group section.
     83   ResolveInfo* readSignature(Input& pInput,
     84                              LDSection& pSymTab,
     85                              uint32_t pSymIdx) const;
     86 
     87   /// readRela - read ELF rela and create Relocation
     88   bool readRela(Input& pInput,
     89                 LDSection& pSection,
     90                 llvm::StringRef pRegion) const;
     91 
     92   /// readRel - read ELF rel and create Relocation
     93   bool readRel(Input& pInput,
     94                LDSection& pSection,
     95                llvm::StringRef pRegion) const;
     96 
     97   /// readDynamic - read ELF .dynamic in input dynobj
     98   bool readDynamic(Input& pInput) const;
     99 
    100 private:
    101   struct AliasInfo {
    102     LDSymbol* pt_alias; ///potential alias
    103     uint64_t ld_value;
    104     ResolveInfo::Binding ld_binding;
    105   };
    106 
    107   /// comparison function to sort symbols for analyzing weak alias.
    108   /// sort symbols by symbol value and then weak before strong.
    109   /// ref. to gold symtabl.cc 1595
    110   static bool less(AliasInfo p1, AliasInfo p2) {
    111     if (p1.ld_value != p2.ld_value)
    112       return (p1.ld_value < p2.ld_value);
    113     if (p1.ld_binding != p2.ld_binding) {
    114       if (ResolveInfo::Weak==p1.ld_binding)
    115         return true;
    116       else if (ResolveInfo::Weak==p2.ld_binding)
    117         return false;
    118     }
    119     return p1.pt_alias->str() < p2.pt_alias->str();
    120   }
    121 
    122 };
    123 
    124 
    125 /** \class ELFReader<64, true>
    126  *  \brief ELFReader<64, true> is a 64-bit, little endian ELFReader.
    127  */
    128 template<>
    129 class ELFReader<64, true> : public ELFReaderIF
    130 {
    131 public:
    132   typedef llvm::ELF::Elf64_Ehdr ELFHeader;
    133   typedef llvm::ELF::Elf64_Shdr SectionHeader;
    134   typedef llvm::ELF::Elf64_Sym  Symbol;
    135   typedef llvm::ELF::Elf64_Rel  Rel;
    136   typedef llvm::ELF::Elf64_Rela Rela;
    137 
    138 public:
    139   ELFReader(GNULDBackend& pBackend);
    140 
    141   ~ELFReader();
    142 
    143   /// ELFHeaderSize - return the size of the ELFHeader
    144   size_t getELFHeaderSize() const
    145   { return sizeof(ELFHeader); }
    146 
    147   /// isELF - is this a ELF file
    148   bool isELF(const void* pELFHeader) const;
    149 
    150   /// isMyEndian - is this ELF file in the same endian to me?
    151   bool isMyEndian(const void* pELFHeader) const;
    152 
    153   /// isMyMachine - is this ELF file generated for the same machine.
    154   bool isMyMachine(const void* pELFHeader) const;
    155 
    156   /// fileType - the file type of this file
    157   Input::Type fileType(const void* pELFHeader) const;
    158 
    159   /// readSectionHeaders - read ELF section header table and create LDSections
    160   bool readSectionHeaders(Input& pInput, const void* pELFHeader) const;
    161 
    162   /// readRegularSection - read a regular section and create fragments.
    163   bool readRegularSection(Input& pInput, SectionData& pSD) const;
    164 
    165   /// readSymbols - read ELF symbols and create LDSymbol
    166   bool readSymbols(Input& pInput,
    167                    IRBuilder& pBuilder,
    168                    llvm::StringRef pRegion,
    169                    const char* StrTab) const;
    170 
    171   /// readSignature - read a symbol from the given Input and index in symtab
    172   /// This is used to get the signature of a group section.
    173   ResolveInfo* readSignature(Input& pInput,
    174                              LDSection& pSymTab,
    175                              uint32_t pSymIdx) const;
    176 
    177   /// readRela - read ELF rela and create Relocation
    178   bool readRela(Input& pInput,
    179                 LDSection& pSection,
    180                 llvm::StringRef pRegion) const;
    181 
    182   /// readRel - read ELF rel and create Relocation
    183   bool readRel(Input& pInput,
    184                LDSection& pSection,
    185                llvm::StringRef pRegion) const;
    186 
    187   /// readDynamic - read ELF .dynamic in input dynobj
    188   bool readDynamic(Input& pInput) const;
    189 
    190 private:
    191   struct AliasInfo {
    192     LDSymbol* pt_alias; ///potential alias
    193     uint64_t ld_value;
    194     ResolveInfo::Binding ld_binding;
    195   };
    196 
    197   /// comparison function to sort symbols for analyzing weak alias.
    198   /// sort symbols by symbol value and then weak before strong.
    199   /// ref. to gold symtabl.cc 1595
    200   static bool less(AliasInfo p1, AliasInfo p2) {
    201     if (p1.ld_value != p2.ld_value)
    202       return (p1.ld_value < p2.ld_value);
    203     if (p1.ld_binding != p2.ld_binding) {
    204       if (ResolveInfo::Weak==p1.ld_binding)
    205         return true;
    206       else if (ResolveInfo::Weak==p2.ld_binding)
    207         return false;
    208     }
    209     return p1.pt_alias->str() < p2.pt_alias->str();
    210   }
    211 
    212 };
    213 
    214 } // namespace of mcld
    215 
    216 #endif
    217 
    218