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