//===- lib/ReaderWriter/ELF/MipsELFFile.h ---------------------------------===// // // The LLVM Linker // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// #ifndef LLD_READER_WRITER_ELF_MIPS_MIPS_ELF_FILE_H #define LLD_READER_WRITER_ELF_MIPS_MIPS_ELF_FILE_H #include "ELFReader.h" #include "MipsLinkingContext.h" #include "MipsRelocationHandler.h" #include "llvm/ADT/STLExtras.h" namespace lld { namespace elf { template class MipsELFFile; template class MipsELFDefinedAtom : public ELFDefinedAtom { typedef llvm::object::Elf_Sym_Impl Elf_Sym; typedef llvm::object::Elf_Shdr_Impl Elf_Shdr; public: MipsELFDefinedAtom(const MipsELFFile &file, StringRef symbolName, StringRef sectionName, const Elf_Sym *symbol, const Elf_Shdr *section, ArrayRef contentData, unsigned int referenceStart, unsigned int referenceEnd, std::vector *> &referenceList); const MipsELFFile& file() const override; DefinedAtom::CodeModel codeModel() const override; bool isPIC() const; }; template class MipsELFReference : public ELFReference { typedef llvm::object::Elf_Rel_Impl Elf_Rel; typedef llvm::object::Elf_Rel_Impl Elf_Rela; public: MipsELFReference(uint64_t symValue, const Elf_Rela &rel); MipsELFReference(uint64_t symValue, const Elf_Rel &rel); uint32_t tag() const override { return _tag; } void setTag(uint32_t tag) { _tag = tag; } private: uint32_t _tag; }; template class MipsELFFile : public ELFFile { public: MipsELFFile(std::unique_ptr mb, ELFLinkingContext &ctx); bool isPIC() const; /// \brief gp register value stored in the .reginfo section. int64_t getGP0() const { return _gp0; } /// \brief .tdata section address plus fixed offset. uint64_t getTPOffset() const { return _tpOff; } uint64_t getDTPOffset() const { return _dtpOff; } protected: std::error_code doParse() override; private: typedef llvm::object::Elf_Sym_Impl Elf_Sym; typedef llvm::object::Elf_Shdr_Impl Elf_Shdr; typedef typename llvm::object::ELFFile::Elf_Rel Elf_Rel; typedef typename llvm::object::ELFFile::Elf_Rela Elf_Rela; enum { TP_OFFSET = 0x7000, DTP_OFFSET = 0x8000 }; int64_t _gp0 = 0; uint64_t _tpOff = 0; uint64_t _dtpOff = 0; ELFDefinedAtom * createDefinedAtom(StringRef symName, StringRef sectionName, const Elf_Sym *sym, const Elf_Shdr *sectionHdr, ArrayRef contentData, unsigned int referenceStart, unsigned int referenceEnd, std::vector *> &referenceList) override; void createRelocationReferences(const Elf_Sym *symbol, ArrayRef content, range rels) override; void createRelocationReferences(const Elf_Sym *symbol, ArrayRef symContent, ArrayRef secContent, const Elf_Shdr *RelSec) override; const Elf_Shdr *findSectionByType(uint64_t type) const; const Elf_Shdr *findSectionByFlags(uint64_t flags) const; typedef typename llvm::object::ELFFile::Elf_Ehdr Elf_Ehdr; typedef llvm::object::Elf_Mips_RegInfo Elf_Mips_RegInfo; typedef llvm::object::Elf_Mips_Options Elf_Mips_Options; typedef llvm::object::Elf_Mips_ABIFlags Elf_Mips_ABIFlags; ErrorOr findRegInfoSec() const; ErrorOr findAbiFlagsSec() const; std::error_code readAuxData(); Reference::Addend readAddend(const Elf_Rel &ri, const ArrayRef content) const; uint32_t getPairRelocation(const Elf_Shdr *Symtab, const Elf_Rel &rel) const; const Elf_Rel *findMatchingRelocation(uint32_t pairRelType, const Elf_Rel *rit, const Elf_Rel *eit) const; bool isLocalBinding(const Elf_Shdr *Symtab, const Elf_Rel &rel) const; }; } // elf } // lld #endif