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