//===- lib/ReaderWriter/ELF/HexagonELFFile.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_HEXAGON_ELF_FILE_H #define LLD_READER_WRITER_ELF_HEXAGON_ELF_FILE_H #include "ELFReader.h" #include "HexagonLinkingContext.h" namespace lld { namespace elf { template class HexagonELFFile; template class HexagonELFDefinedAtom : public ELFDefinedAtom { typedef llvm::object::Elf_Sym_Impl Elf_Sym; typedef llvm::object::Elf_Shdr_Impl Elf_Shdr; public: HexagonELFDefinedAtom(const HexagonELFFile &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) {} virtual DefinedAtom::ContentType contentType() const { if (this->_contentType != DefinedAtom::typeUnknown) return this->_contentType; else if (this->_section->sh_flags & llvm::ELF::SHF_HEX_GPREL) { if (this->_section->sh_type == llvm::ELF::SHT_NOBITS) return (this->_contentType = DefinedAtom::typeZeroFillFast); else return (this->_contentType = DefinedAtom::typeDataFast); } return ELFDefinedAtom::contentType(); } virtual DefinedAtom::ContentPermissions permissions() const { if (this->_section->sh_flags & llvm::ELF::SHF_HEX_GPREL) return DefinedAtom::permRW_; return ELFDefinedAtom::permissions(); } }; template class HexagonELFCommonAtom : public ELFCommonAtom { typedef llvm::object::Elf_Sym_Impl Elf_Sym; typedef llvm::object::Elf_Shdr_Impl Elf_Shdr; public: HexagonELFCommonAtom(const HexagonELFFile &file, StringRef symbolName, const Elf_Sym *symbol) : ELFCommonAtom(file, symbolName, symbol) {} virtual bool isSmallCommonSymbol() const { switch (this->_symbol->st_shndx) { // Common symbols case llvm::ELF::SHN_HEXAGON_SCOMMON: case llvm::ELF::SHN_HEXAGON_SCOMMON_1: case llvm::ELF::SHN_HEXAGON_SCOMMON_2: case llvm::ELF::SHN_HEXAGON_SCOMMON_4: case llvm::ELF::SHN_HEXAGON_SCOMMON_8: return true; default: break; } return false; } virtual uint64_t size() const { if (isSmallCommonSymbol()) return this->_symbol->st_size; return ELFCommonAtom::size(); } virtual DefinedAtom::Merge merge() const { if (this->_symbol->getBinding() == llvm::ELF::STB_WEAK) return DefinedAtom::mergeAsWeak; if (isSmallCommonSymbol()) return DefinedAtom::mergeAsTentative; return ELFCommonAtom::merge(); } virtual DefinedAtom::ContentType contentType() const { if (isSmallCommonSymbol()) return DefinedAtom::typeZeroFillFast; return ELFCommonAtom::contentType(); } virtual DefinedAtom::Alignment alignment() const { if (isSmallCommonSymbol()) return DefinedAtom::Alignment(llvm::Log2_64(this->_symbol->st_value)); return ELFCommonAtom::alignment(); } virtual DefinedAtom::ContentPermissions permissions() const { if (isSmallCommonSymbol()) return DefinedAtom::permRW_; return ELFCommonAtom::permissions(); } }; template class HexagonELFFile : public ELFFile { typedef llvm::object::Elf_Sym_Impl Elf_Sym; typedef llvm::object::Elf_Shdr_Impl Elf_Shdr; public: HexagonELFFile(std::unique_ptr mb, HexagonLinkingContext &ctx) : ELFFile(std::move(mb), ctx) {} static ErrorOr> create(std::unique_ptr mb, HexagonLinkingContext &ctx) { return std::unique_ptr>( new HexagonELFFile(std::move(mb), ctx)); } bool isCommonSymbol(const Elf_Sym *symbol) const override { switch (symbol->st_shndx) { // Common symbols case llvm::ELF::SHN_HEXAGON_SCOMMON: case llvm::ELF::SHN_HEXAGON_SCOMMON_1: case llvm::ELF::SHN_HEXAGON_SCOMMON_2: case llvm::ELF::SHN_HEXAGON_SCOMMON_4: case llvm::ELF::SHN_HEXAGON_SCOMMON_8: return true; default: break; } return ELFFile::isCommonSymbol(symbol); } /// 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) HexagonELFDefinedAtom( *this, symName, sectionName, sym, sectionHdr, contentData, referenceStart, referenceEnd, referenceList); } /// Process the Common symbol and create an atom for it. ErrorOr *> handleCommonSymbol(StringRef symName, const Elf_Sym *sym) override { return new (this->_readerStorage) HexagonELFCommonAtom(*this, symName, sym); } }; template class HexagonDynamicFile : public DynamicFile { public: HexagonDynamicFile(const HexagonLinkingContext &context, StringRef name) : DynamicFile(context, name) {} }; } // elf } // lld #endif // LLD_READER_WRITER_ELF_HEXAGON_ELF_FILE_H