//===--------- lib/ReaderWriter/ELF/ARM/ARMELFFile.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_ARM_ARM_ELF_FILE_H #define LLD_READER_WRITER_ELF_ARM_ARM_ELF_FILE_H #include "ELFReader.h" namespace lld { namespace elf { class ARMLinkingContext; template class ARMELFDefinedAtom : public ELFDefinedAtom { typedef llvm::object::Elf_Sym_Impl Elf_Sym; typedef llvm::object::Elf_Shdr_Impl Elf_Shdr; public: ARMELFDefinedAtom(const ELFFile &file, StringRef symbolName, StringRef sectionName, const Elf_Sym *symbol, const Elf_Shdr *section, ArrayRef contentData, unsigned int referenceStart, unsigned int referenceEnd, std::vector *> &referenceList) : ELFDefinedAtom(file, symbolName, sectionName, symbol, section, contentData, referenceStart, referenceEnd, referenceList) {} bool isThumbFunc(const Elf_Sym *symbol) const { return symbol->getType() == llvm::ELF::STT_FUNC && (static_cast(symbol->st_value) & 0x1); } /// Correct st_value for symbols addressing Thumb instructions /// by removing its zero bit. uint64_t getSymbolValue(const Elf_Sym *symbol) const override { const auto value = static_cast(symbol->st_value); return isThumbFunc(symbol) ? value & ~0x1 : value; } DefinedAtom::CodeModel codeModel() const override { if (isThumbFunc(this->_symbol)) return DefinedAtom::codeARMThumb; return DefinedAtom::codeNA; } }; template class ARMELFFile : public ELFFile { public: ARMELFFile(std::unique_ptr mb, ARMLinkingContext &ctx) : ELFFile(std::move(mb), ctx) {} static ErrorOr> create(std::unique_ptr mb, ARMLinkingContext &ctx) { return std::unique_ptr>( new ARMELFFile(std::move(mb), ctx)); } private: typedef llvm::object::Elf_Sym_Impl Elf_Sym; typedef llvm::object::Elf_Shdr_Impl Elf_Shdr; /// Correct st_value for symbols addressing Thumb instructions /// by removing its zero bit. uint64_t getSymbolValue(const Elf_Sym *symbol) const override { const auto value = static_cast(symbol->st_value); return symbol->getType() == llvm::ELF::STT_FUNC ? value & ~0x1 : value; } /// Process the Defined symbol and create an atom for it. ErrorOr *> handleDefinedSymbol(StringRef symName, StringRef sectionName, const Elf_Sym *sym, const Elf_Shdr *sectionHdr, ArrayRef contentData, unsigned int referenceStart, unsigned int referenceEnd, std::vector *> &referenceList) override { return new (this->_readerStorage) ARMELFDefinedAtom( *this, symName, sectionName, sym, sectionHdr, contentData, referenceStart, referenceEnd, referenceList); } }; template class ARMDynamicFile : public DynamicFile { public: ARMDynamicFile(const ARMLinkingContext &context, StringRef name) : DynamicFile(context, name) {} }; } // elf } // lld #endif // LLD_READER_WRITER_ELF_ARM_ARM_ELF_FILE_H