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