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