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