| //===- ELFReader.h --------------------------------------------------------===// |
| // |
| // The MCLinker Project |
| // |
| // This file is distributed under the University of Illinois Open Source |
| // License. See LICENSE.TXT for details. |
| // |
| //===----------------------------------------------------------------------===// |
| #ifndef MCLD_ELF_READER_INTERFACE_H |
| #define MCLD_ELF_READER_INTERFACE_H |
| #ifdef ENABLE_UNITTEST |
| #include <gtest.h> |
| #endif |
| |
| #include <llvm/ADT/StringRef.h> |
| #include <llvm/Support/ELF.h> |
| #include <llvm/Support/Host.h> |
| #include <llvm/MC/MCAssembler.h> |
| #include <mcld/MC/MCLDInfo.h> |
| #include <mcld/MC/MCLDInput.h> |
| #include <mcld/MC/MCLinker.h> |
| #include <mcld/MC/MCRegionFragment.h> |
| #include <mcld/LD/ResolveInfo.h> |
| #include <mcld/LD/LDContext.h> |
| #include <mcld/Target/GNULDBackend.h> |
| #include <mcld/Support/MemoryRegion.h> |
| |
| namespace mcld |
| { |
| |
| /** \class ELFReaderIF |
| * \brief ELFReaderIF provides common interface for all kind of ELF readers. |
| */ |
| class ELFReaderIF |
| { |
| public: |
| ELFReaderIF(GNULDBackend& pBackend) |
| : m_Backend(pBackend) |
| { } |
| |
| virtual ~ELFReaderIF() { } |
| |
| /// ELFHeaderSize - return the size of the ELFHeader |
| virtual size_t getELFHeaderSize() const = 0; |
| |
| /// isELF - is this a ELF file |
| virtual bool isELF(void* pELFHeader) const = 0; |
| |
| /// isMyEndian - is this ELF file in the same endian to me? |
| virtual bool isMyEndian(void* pELFHeader) const = 0; |
| |
| /// isMyMachine - is this ELF file generated for the same machine. |
| virtual bool isMyMachine(void* pELFHeader) const = 0; |
| |
| /// fileType - the file type of this file |
| virtual MCLDFile::Type fileType(void* pELFHeader) const = 0; |
| |
| /// target - the target backend |
| GNULDBackend& target() |
| { return m_Backend; } |
| |
| /// target - the target backend |
| const GNULDBackend& target() const |
| { return m_Backend; } |
| |
| /// readSectionHeaders - read ELF section header table and create LDSections |
| virtual bool readSectionHeaders(Input& pInput, |
| MCLinker& pLinker, |
| void* pELFHeader) const = 0; |
| |
| /// readRegularSection - read a regular section and create fragments. |
| virtual bool readRegularSection(Input& pInput, |
| MCLinker& pLinker, |
| LDSection& pSectHdr) const = 0; |
| |
| /// readRegularSection - read a target section and create fragments. |
| virtual bool readTargetSection(Input& pInput, |
| MCLinker& pLinker, |
| LDSection& pSectHdr) = 0; |
| |
| /// readSymbols - read ELF symbols and create LDSymbol |
| virtual bool readSymbols(Input& pInput, |
| MCLinker& pLinker, |
| const MemoryRegion& pRegion, |
| const char* StrTab) const = 0; |
| |
| /// readSymbol - read a symbol from the given Input and index in symtab |
| virtual ResolveInfo* readSymbol(Input& pInput, |
| LDSection& pSymTab, |
| MCLDInfo& pLDInfo, |
| uint32_t pSymIdx) const = 0; |
| |
| /// readRela - read ELF rela and create Relocation |
| virtual bool readRela(Input& pInput, |
| MCLinker& pLinker, |
| LDSection& pSection, |
| const MemoryRegion& pRegion) const = 0; |
| |
| /// readRel - read ELF rel and create Relocation |
| virtual bool readRel(Input& pInput, |
| MCLinker& pLinker, |
| LDSection& pSection, |
| const MemoryRegion& pRegion) const = 0; |
| protected: |
| /// LinkInfo - some section needs sh_link and sh_info, remember them. |
| struct LinkInfo { |
| LDSection* section; |
| uint32_t sh_link; |
| uint32_t sh_info; |
| }; |
| |
| typedef std::vector<LinkInfo> LinkInfoList; |
| |
| protected: |
| LDFileFormat::Kind getLDSectionKind(uint32_t pType, const char* pName) const; |
| |
| ResolveInfo::Desc getSymDesc(uint16_t pShndx, const Input& pInput) const; |
| |
| ResolveInfo::Binding getSymBinding(uint8_t pBinding, |
| uint16_t pShndx, |
| uint8_t pVisibility) const; |
| |
| uint64_t getSymValue(uint64_t pValue, |
| uint16_t pShndx, |
| const Input& pInput) const; |
| |
| MCFragmentRef* getSymFragmentRef(Input& pInput, |
| MCLinker& pLinker, |
| uint16_t pShndx, |
| uint32_t pOffset) const; |
| |
| ResolveInfo::Visibility getSymVisibility(uint8_t pVis) const; |
| |
| private: |
| GNULDBackend& m_Backend; |
| }; |
| |
| /** \class ELFReader |
| * \brief ELFReader is a template scaffolding for partial specification. |
| */ |
| template<size_t BIT, bool LITTLEENDIAN> |
| class ELFReader |
| { }; |
| |
| /** \class ELFReader<32, true> |
| * \brief ELFReader<32, true> is a 32-bit, little endian ELFReader. |
| */ |
| template<> |
| class ELFReader<32, true> : public ELFReaderIF |
| { |
| public: |
| typedef llvm::ELF::Elf32_Ehdr ELFHeader; |
| typedef llvm::ELF::Elf32_Shdr SectionHeader; |
| typedef llvm::ELF::Elf32_Sym Symbol; |
| typedef llvm::ELF::Elf32_Rel Rel; |
| typedef llvm::ELF::Elf32_Rela Rela; |
| |
| public: |
| inline ELFReader(GNULDBackend& pBackend); |
| |
| inline ~ELFReader(); |
| |
| /// ELFHeaderSize - return the size of the ELFHeader |
| inline size_t getELFHeaderSize() const |
| { return sizeof(ELFHeader); } |
| |
| /// isELF - is this a ELF file |
| inline bool isELF(void* pELFHeader) const; |
| |
| /// isMyEndian - is this ELF file in the same endian to me? |
| inline bool isMyEndian(void* pELFHeader) const; |
| |
| /// isMyMachine - is this ELF file generated for the same machine. |
| inline bool isMyMachine(void* pELFHeader) const; |
| |
| /// fileType - the file type of this file |
| inline MCLDFile::Type fileType(void* pELFHeader) const; |
| |
| /// readSectionHeaders - read ELF section header table and create LDSections |
| inline bool readSectionHeaders(Input& pInput, |
| MCLinker& pLinker, |
| void* pELFHeader) const; |
| |
| /// readRegularSection - read a regular section and create fragments. |
| inline bool readRegularSection(Input& pInput, |
| MCLinker& pLinker, |
| LDSection& pInputSectHdr) const; |
| |
| /// readRegularSection - read a target section and create fragments. |
| inline bool readTargetSection(Input& pInput, |
| MCLinker& pLinker, |
| LDSection& pInputSectHdr); |
| |
| /// readSymbols - read ELF symbols and create LDSymbol |
| inline bool readSymbols(Input& pInput, |
| MCLinker& pLinker, |
| const MemoryRegion& pRegion, |
| const char* StrTab) const; |
| |
| /// readSymbol - read a symbol from the given Input and index in symtab |
| inline ResolveInfo* readSymbol(Input& pInput, |
| LDSection& pSymTab, |
| MCLDInfo& pLDInfo, |
| uint32_t pSymIdx) const; |
| |
| /// readRela - read ELF rela and create Relocation |
| inline bool readRela(Input& pInput, |
| MCLinker& pLinker, |
| LDSection& pSection, |
| const MemoryRegion& pRegion) const; |
| |
| /// readRel - read ELF rel and create Relocation |
| inline bool readRel(Input& pInput, |
| MCLinker& pLinker, |
| LDSection& pSection, |
| const MemoryRegion& pRegion) const; |
| }; |
| |
| #include "ELFReader.tcc" |
| |
| } // namespace of mcld |
| |
| #endif |