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_INTERFACE_H 10 #define MCLD_ELF_READER_INTERFACE_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 #include <llvm/MC/MCAssembler.h> 19 #include <mcld/MC/MCLDInfo.h> 20 #include <mcld/MC/MCLDInput.h> 21 #include <mcld/MC/MCLinker.h> 22 #include <mcld/MC/MCRegionFragment.h> 23 #include <mcld/LD/ResolveInfo.h> 24 #include <mcld/LD/LDContext.h> 25 #include <mcld/Target/GNULDBackend.h> 26 #include <mcld/Support/MemoryRegion.h> 27 28 namespace mcld 29 { 30 31 /** \class ELFReaderIF 32 * \brief ELFReaderIF provides common interface for all kind of ELF readers. 33 */ 34 class ELFReaderIF 35 { 36 public: 37 ELFReaderIF(GNULDBackend& pBackend) 38 : m_Backend(pBackend) 39 { } 40 41 virtual ~ELFReaderIF() { } 42 43 /// ELFHeaderSize - return the size of the ELFHeader 44 virtual size_t getELFHeaderSize() const = 0; 45 46 /// isELF - is this a ELF file 47 virtual bool isELF(void* pELFHeader) const = 0; 48 49 /// isMyEndian - is this ELF file in the same endian to me? 50 virtual bool isMyEndian(void* pELFHeader) const = 0; 51 52 /// isMyMachine - is this ELF file generated for the same machine. 53 virtual bool isMyMachine(void* pELFHeader) const = 0; 54 55 /// fileType - the file type of this file 56 virtual MCLDFile::Type fileType(void* pELFHeader) const = 0; 57 58 /// target - the target backend 59 GNULDBackend& target() 60 { return m_Backend; } 61 62 /// target - the target backend 63 const GNULDBackend& target() const 64 { return m_Backend; } 65 66 /// readSectionHeaders - read ELF section header table and create LDSections 67 virtual bool readSectionHeaders(Input& pInput, 68 MCLinker& pLinker, 69 void* pELFHeader) const = 0; 70 71 /// readRegularSection - read a regular section and create fragments. 72 virtual bool readRegularSection(Input& pInput, 73 MCLinker& pLinker, 74 LDSection& pSectHdr) const = 0; 75 76 /// readRegularSection - read a target section and create fragments. 77 virtual bool readTargetSection(Input& pInput, 78 MCLinker& pLinker, 79 LDSection& pSectHdr) = 0; 80 81 /// readSymbols - read ELF symbols and create LDSymbol 82 virtual bool readSymbols(Input& pInput, 83 MCLinker& pLinker, 84 const MemoryRegion& pRegion, 85 const char* StrTab) const = 0; 86 87 /// readSymbol - read a symbol from the given Input and index in symtab 88 virtual ResolveInfo* readSymbol(Input& pInput, 89 LDSection& pSymTab, 90 MCLDInfo& pLDInfo, 91 uint32_t pSymIdx) const = 0; 92 93 /// readRela - read ELF rela and create Relocation 94 virtual bool readRela(Input& pInput, 95 MCLinker& pLinker, 96 LDSection& pSection, 97 const MemoryRegion& pRegion) const = 0; 98 99 /// readRel - read ELF rel and create Relocation 100 virtual bool readRel(Input& pInput, 101 MCLinker& pLinker, 102 LDSection& pSection, 103 const MemoryRegion& pRegion) const = 0; 104 protected: 105 /// LinkInfo - some section needs sh_link and sh_info, remember them. 106 struct LinkInfo { 107 LDSection* section; 108 uint32_t sh_link; 109 uint32_t sh_info; 110 }; 111 112 typedef std::vector<LinkInfo> LinkInfoList; 113 114 protected: 115 LDFileFormat::Kind getLDSectionKind(uint32_t pType, const char* pName) const; 116 117 ResolveInfo::Desc getSymDesc(uint16_t pShndx, const Input& pInput) const; 118 119 ResolveInfo::Binding getSymBinding(uint8_t pBinding, 120 uint16_t pShndx, 121 uint8_t pVisibility) const; 122 123 uint64_t getSymValue(uint64_t pValue, 124 uint16_t pShndx, 125 const Input& pInput) const; 126 127 MCFragmentRef* getSymFragmentRef(Input& pInput, 128 MCLinker& pLinker, 129 uint16_t pShndx, 130 uint32_t pOffset) const; 131 132 ResolveInfo::Visibility getSymVisibility(uint8_t pVis) const; 133 134 private: 135 GNULDBackend& m_Backend; 136 }; 137 138 /** \class ELFReader 139 * \brief ELFReader is a template scaffolding for partial specification. 140 */ 141 template<size_t BIT, bool LITTLEENDIAN> 142 class ELFReader 143 { }; 144 145 /** \class ELFReader<32, true> 146 * \brief ELFReader<32, true> is a 32-bit, little endian ELFReader. 147 */ 148 template<> 149 class ELFReader<32, true> : public ELFReaderIF 150 { 151 public: 152 typedef llvm::ELF::Elf32_Ehdr ELFHeader; 153 typedef llvm::ELF::Elf32_Shdr SectionHeader; 154 typedef llvm::ELF::Elf32_Sym Symbol; 155 typedef llvm::ELF::Elf32_Rel Rel; 156 typedef llvm::ELF::Elf32_Rela Rela; 157 158 public: 159 inline ELFReader(GNULDBackend& pBackend); 160 161 inline ~ELFReader(); 162 163 /// ELFHeaderSize - return the size of the ELFHeader 164 inline size_t getELFHeaderSize() const 165 { return sizeof(ELFHeader); } 166 167 /// isELF - is this a ELF file 168 inline bool isELF(void* pELFHeader) const; 169 170 /// isMyEndian - is this ELF file in the same endian to me? 171 inline bool isMyEndian(void* pELFHeader) const; 172 173 /// isMyMachine - is this ELF file generated for the same machine. 174 inline bool isMyMachine(void* pELFHeader) const; 175 176 /// fileType - the file type of this file 177 inline MCLDFile::Type fileType(void* pELFHeader) const; 178 179 /// readSectionHeaders - read ELF section header table and create LDSections 180 inline bool readSectionHeaders(Input& pInput, 181 MCLinker& pLinker, 182 void* pELFHeader) const; 183 184 /// readRegularSection - read a regular section and create fragments. 185 inline bool readRegularSection(Input& pInput, 186 MCLinker& pLinker, 187 LDSection& pInputSectHdr) const; 188 189 /// readRegularSection - read a target section and create fragments. 190 inline bool readTargetSection(Input& pInput, 191 MCLinker& pLinker, 192 LDSection& pInputSectHdr); 193 194 /// readSymbols - read ELF symbols and create LDSymbol 195 inline bool readSymbols(Input& pInput, 196 MCLinker& pLinker, 197 const MemoryRegion& pRegion, 198 const char* StrTab) const; 199 200 /// readSymbol - read a symbol from the given Input and index in symtab 201 inline ResolveInfo* readSymbol(Input& pInput, 202 LDSection& pSymTab, 203 MCLDInfo& pLDInfo, 204 uint32_t pSymIdx) const; 205 206 /// readRela - read ELF rela and create Relocation 207 inline bool readRela(Input& pInput, 208 MCLinker& pLinker, 209 LDSection& pSection, 210 const MemoryRegion& pRegion) const; 211 212 /// readRel - read ELF rel and create Relocation 213 inline bool readRel(Input& pInput, 214 MCLinker& pLinker, 215 LDSection& pSection, 216 const MemoryRegion& pRegion) const; 217 }; 218 219 #include "ELFReader.tcc" 220 221 } // namespace of mcld 222 223 #endif 224