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