Index: include/lld/Core/DefinedAtom.h =================================================================== --- include/lld/Core/DefinedAtom.h +++ include/lld/Core/DefinedAtom.h @@ -123,6 +123,7 @@ typeLiteral8, // an eight-btye read-only constant typeLiteral16, // a sixteen-btye read-only constant typeData, // read-write data + typeDataQuicker, // allow data to be quickly accessed typeZeroFill, // zero-fill data typeConstData, // read-only data after dynamic linker is done typeObjC1Class, // ObjC1 class [Darwin] Index: lib/Core/DefinedAtom.cpp =================================================================== --- lib/Core/DefinedAtom.cpp +++ lib/Core/DefinedAtom.cpp @@ -44,6 +44,7 @@ return permR__; case typeData: + case typeDataQuicker: case typeZeroFill: case typeObjC1Class: case typeLazyPointer: Index: lib/ReaderWriter/ELF/Atoms.h =================================================================== --- lib/ReaderWriter/ELF/Atoms.h +++ lib/ReaderWriter/ELF/Atoms.h @@ -200,12 +200,27 @@ return _ordinal; } + const Elf_Sym *symbol() const { return _symbol; } + + const Elf_Shdr *section() const { return _section; } + virtual uint64_t size() const { // Common symbols are not allocated in object files, // so use st_size to tell how many bytes are required. - if ((_symbol->getType() == llvm::ELF::STT_COMMON) - || _symbol->st_shndx == llvm::ELF::SHN_COMMON) - return (uint64_t)_symbol->st_size; + + // Treat target defined common symbols + if ((_symbol->st_shndx > llvm::ELF::SHN_LOPROC && + _symbol->st_shndx < llvm::ELF::SHN_HIPROC)) { + const ELFTargetInfo &eti = (_owningFile.getTargetInfo()); + TargetHandler &TargetHandler = eti.getTargetHandler(); + TargetAtomHandler &elfAtomHandler = + TargetHandler.targetAtomHandler(); + if (elfAtomHandler.getType(_symbol) == llvm::ELF::STT_COMMON) + return (uint64_t) _symbol->st_size; + } + if ((_symbol->getType() == llvm::ELF::STT_COMMON) || + _symbol->st_shndx == llvm::ELF::SHN_COMMON) + return (uint64_t) _symbol->st_size; return _contentData.size(); } @@ -229,8 +244,21 @@ if (_symbol->getBinding() == llvm::ELF::STB_WEAK) return mergeAsWeak; - if ((_symbol->getType() == llvm::ELF::STT_COMMON) - || _symbol->st_shndx == llvm::ELF::SHN_COMMON) + // If the symbol is a target defined and if the target + // defines the symbol as a common symbol treat it as + // mergeTentative + if ((_symbol->st_shndx > llvm::ELF::SHN_LOPROC && + _symbol->st_shndx < llvm::ELF::SHN_HIPROC)) { + const ELFTargetInfo &eti = (_owningFile.getTargetInfo()); + TargetHandler &TargetHandler = eti.getTargetHandler(); + TargetAtomHandler &elfAtomHandler = + TargetHandler.targetAtomHandler(); + if (elfAtomHandler.getType(_symbol) == llvm::ELF::STT_COMMON) + return mergeAsTentative; + } + + if ((_symbol->getType() == llvm::ELF::STT_COMMON) || + _symbol->st_shndx == llvm::ELF::SHN_COMMON) return mergeAsTentative; return mergeNo; @@ -240,12 +268,12 @@ ContentType ret = typeUnknown; uint64_t flags = _section->sh_flags; - if (_symbol->st_shndx > llvm::ELF::SHN_LOPROC && - _symbol->st_shndx < llvm::ELF::SHN_HIPROC) { - const ELFTargetInfo &eti = - (_owningFile.getTargetInfo()); - TargetHandler &TargetHandler = - eti.getTargetHandler(); + // Treat target defined symbols + if ((_section->sh_flags & llvm::ELF::SHF_MASKPROC) || + ((_symbol->st_shndx > llvm::ELF::SHN_LOPROC && + _symbol->st_shndx < llvm::ELF::SHN_HIPROC))) { + const ELFTargetInfo &eti = (_owningFile.getTargetInfo()); + TargetHandler &TargetHandler = eti.getTargetHandler(); TargetAtomHandler &elfAtomHandler = TargetHandler.targetAtomHandler(); return elfAtomHandler.contentType(this); @@ -303,8 +331,20 @@ virtual Alignment alignment() const { // Unallocated common symbols specify their alignment constraints in // st_value. - if ((_symbol->getType() == llvm::ELF::STT_COMMON) - || _symbol->st_shndx == llvm::ELF::SHN_COMMON) { + + // Treat target defined common symbols + if ((_symbol->st_shndx > llvm::ELF::SHN_LOPROC && + _symbol->st_shndx < llvm::ELF::SHN_HIPROC)) { + const ELFTargetInfo &eti = (_owningFile.getTargetInfo()); + TargetHandler &TargetHandler = eti.getTargetHandler(); + TargetAtomHandler &elfAtomHandler = + TargetHandler.targetAtomHandler(); + if (elfAtomHandler.getType(_symbol) == llvm::ELF::STT_COMMON) + return Alignment(llvm::Log2_64(_symbol->st_value)); + } + + if ((_symbol->getType() == llvm::ELF::STT_COMMON) || + _symbol->st_shndx == llvm::ELF::SHN_COMMON) { return Alignment(llvm::Log2_64(_symbol->st_value)); } return Alignment(llvm::Log2_64(_section->sh_addralign), Index: lib/ReaderWriter/ELF/DefaultLayout.h =================================================================== --- lib/ReaderWriter/ELF/DefaultLayout.h +++ lib/ReaderWriter/ELF/DefaultLayout.h @@ -293,12 +293,12 @@ case DefinedAtom::typeConstant: return ORDER_RODATA; - + case DefinedAtom::typeData: + case DefinedAtom::typeDataQuicker: return llvm::StringSwitch(name) - .StartsWith(".init_array", ORDER_INIT_ARRAY) - .Default(ORDER_DATA); - + .StartsWith(".init_array", ORDER_INIT_ARRAY).Default(ORDER_DATA); + case DefinedAtom::typeZeroFill: return ORDER_BSS; Index: lib/ReaderWriter/ELF/File.h =================================================================== --- lib/ReaderWriter/ELF/File.h +++ lib/ReaderWriter/ELF/File.h @@ -358,18 +358,16 @@ bool isCommon = (*si)->getType() == llvm::ELF::STT_COMMON || (*si)->st_shndx == llvm::ELF::SHN_COMMON; - DefinedAtom::ContentType c; - - if (((*si)->st_shndx >= llvm::ELF::SHN_LOPROC) && - ((*si)->st_shndx <= llvm::ELF::SHN_HIPROC)) { + if ((section && section->sh_flags & llvm::ELF::SHF_MASKPROC) || + (((*si)->st_shndx >= llvm::ELF::SHN_LOPROC) && + ((*si)->st_shndx <= llvm::ELF::SHN_HIPROC))) { TargetHandler &TargetHandler = - _elfTargetInfo.getTargetHandler(); + _elfTargetInfo.template getTargetHandler(); TargetAtomHandler &elfAtomHandler = TargetHandler.targetAtomHandler(); - c = elfAtomHandler.contentType(*si); + int64_t targetSymType = elfAtomHandler.getType(*si); - if (c == DefinedAtom::typeZeroFill || - c == DefinedAtom::typeTLVInitialZeroFill) + if (targetSymType == llvm::ELF::STT_COMMON) isCommon = true; } Index: lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.h =================================================================== --- lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.h +++ lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.h @@ -11,6 +11,7 @@ #define LLD_READER_WRITER_ELF_HEXAGON_TARGET_HANDLER_H #include "DefaultTargetHandler.h" +#include "ExecutableAtoms.h" #include "HexagonRelocationHandler.h" #include "TargetLayout.h" @@ -19,15 +20,75 @@ typedef llvm::object::ELFType HexagonELFType; class HexagonTargetInfo; -class HexagonTargetHandler LLVM_FINAL - : public DefaultTargetHandler { + +/// \brief Handle Hexagon specific Atoms +template +class HexagonTargetAtomHandler LLVM_FINAL : + public TargetAtomHandler { + typedef llvm::object::Elf_Sym_Impl Elf_Sym; + typedef llvm::object::Elf_Shdr_Impl Elf_Shdr; public: + + virtual DefinedAtom::ContentType + contentType(const ELFDefinedAtom *atom) const { + return contentType(atom->section(), atom->symbol()); + } + + virtual DefinedAtom::ContentType + contentType(const Elf_Shdr *section, const Elf_Sym *sym) const { + switch (sym->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 DefinedAtom::typeZeroFill; + + default: + if (section->sh_flags & llvm::ELF::SHF_HEX_GPREL) + return DefinedAtom::typeDataQuicker; + else + llvm_unreachable("unknown symbol type"); + } + } + + virtual DefinedAtom::ContentPermissions + contentPermissions(const ELFDefinedAtom *atom) const { + // All of the hexagon specific symbols belong in the data segment + return DefinedAtom::permRW_; + } + + virtual int64_t getType(const Elf_Sym *sym) const { + switch (sym->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 llvm::ELF::STT_COMMON; + + default: + return sym->getType(); + } + } +}; + +/// \brief TargetHandler for Hexagon +class HexagonTargetHandler LLVM_FINAL : + public DefaultTargetHandler { +public: HexagonTargetHandler(HexagonTargetInfo &targetInfo); virtual TargetLayout &targetLayout() { return _targetLayout; } + virtual TargetAtomHandler &targetAtomHandler() { + return _targetAtomHandler; + } + virtual const HexagonTargetRelocationHandler &getRelocationHandler() const { return _relocationHandler; } @@ -35,6 +96,7 @@ private: HexagonTargetRelocationHandler _relocationHandler; TargetLayout _targetLayout; + HexagonTargetAtomHandler _targetAtomHandler; }; } // end namespace elf } // end namespace lld Index: lib/ReaderWriter/ELF/SectionChunks.h =================================================================== --- lib/ReaderWriter/ELF/SectionChunks.h +++ lib/ReaderWriter/ELF/SectionChunks.h @@ -113,6 +113,7 @@ this->setOrder(order); switch (contentType) { case DefinedAtom::typeCode: + case DefinedAtom::typeDataQuicker: case DefinedAtom::typeData: case DefinedAtom::typeConstant: case DefinedAtom::typeGOT: @@ -261,6 +262,7 @@ case DefinedAtom::typeStub: case DefinedAtom::typeResolver: case DefinedAtom::typeTLVInitialData: + case DefinedAtom::typeDataQuicker: _atoms.push_back(new (_alloc) AtomLayout(atom, fOffset, 0)); this->_fsize = fOffset + definedAtom->size(); this->_msize = mOffset + definedAtom->size(); Index: lib/ReaderWriter/ELF/TargetHandler.h =================================================================== --- lib/ReaderWriter/ELF/TargetHandler.h +++ lib/ReaderWriter/ELF/TargetHandler.h @@ -44,14 +44,16 @@ /// type of atom and its permissions template class TargetAtomHandler { public: + typedef llvm::object::Elf_Shdr_Impl Elf_Shdr; typedef llvm::object::Elf_Sym_Impl Elf_Sym; - virtual DefinedAtom::ContentType contentType( - const ELFDefinedAtom *atom) const { + virtual DefinedAtom::ContentType + contentType(const ELFDefinedAtom *atom) const { return atom->contentType(); } - virtual DefinedAtom::ContentType contentType(const Elf_Sym *sym) const { + virtual DefinedAtom::ContentType + contentType(const Elf_Shdr *shdr, const Elf_Sym *sym) const { return DefinedAtom::typeZeroFill; } @@ -60,6 +62,9 @@ return atom->permissions(); } + virtual int64_t getType(const Elf_Sym *sym) const { + return llvm::ELF::STT_NOTYPE; + } }; template class TargetRelocationHandler { Index: lib/ReaderWriter/YAML/ReaderWriterYAML.cpp =================================================================== --- lib/ReaderWriter/YAML/ReaderWriterYAML.cpp +++ lib/ReaderWriter/YAML/ReaderWriterYAML.cpp @@ -395,14 +395,11 @@ lld::DefinedAtom::typeCode); io.enumCase(value, "stub", lld::DefinedAtom::typeStub); - io.enumCase(value, "constant", - lld::DefinedAtom::typeConstant); - io.enumCase(value, "data", - lld::DefinedAtom::typeData); - io.enumCase(value, "zero-fill", - lld::DefinedAtom::typeZeroFill); - io.enumCase(value, "const-data", - lld::DefinedAtom::typeConstData); + io.enumCase(value, "constant", lld::DefinedAtom::typeConstant); + io.enumCase(value, "data", lld::DefinedAtom::typeData); + io.enumCase(value, "quick-data", lld::DefinedAtom::typeDataQuicker); + io.enumCase(value, "zero-fill", lld::DefinedAtom::typeZeroFill); + io.enumCase(value, "const-data", lld::DefinedAtom::typeConstData); io.enumCase(value, "got", lld::DefinedAtom::typeGOT); io.enumCase(value, "resolver", Index: test/elf/branch.objtxt =================================================================== --- test/elf/branch.objtxt +++ test/elf/branch.objtxt @@ -1,4 +1,4 @@ -RUN: lld-core -reader ELF %p/Inputs/branch-test.hexagon %p/Inputs/target-test.hexagon | FileCheck %s -check-prefix hexagon-yaml +RUN: lld-core -arch hexagon -reader ELF %p/Inputs/branch-test.hexagon %p/Inputs/target-test.hexagon | FileCheck %s -check-prefix hexagon-yaml RUN: lld-core -arch hexagon -reader ELF -writer ELF -o %t1 %p/Inputs/branch-test.hexagon %p/Inputs/target-test.hexagon RUN: elf-dump %t1 | FileCheck -check-prefix=hexagon-elfdump %s Index: test/elf/quickdata.test =================================================================== --- test/elf/quickdata.test +++ test/elf/quickdata.test @@ -0,0 +1,14 @@ +RUN: lld-core -arch hexagon -reader ELF %p/Inputs/quickdata-test.elf-hexagon | FileCheck %s -check-prefix hexagon + +hexagon: - name: init +hexagon: scope: global +hexagon: type: quick-data +hexagon: - name: bss1 +hexagon: scope: global +hexagon: type: quick-data +hexagon: - name: ac1 +hexagon: scope: global +hexagon: type: zero-fill +hexagon: size: 1 +hexagon: merge: as-tentative +hexagon: permissions: ---