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