diff options
author | Rui Ueyama <ruiu@google.com> | 2015-04-14 20:21:53 +0000 |
---|---|---|
committer | Rui Ueyama <ruiu@google.com> | 2015-04-14 20:21:53 +0000 |
commit | 569e11af4667171da6dcb9cf20f6623a734a7e3c (patch) | |
tree | 836a0bbd7003857213f0e4b3b61e6b9e39ce8b43 | |
parent | 2783469116c3b6cf9c77b3a8a40bb3fb24caaa39 (diff) | |
download | bcm5719-llvm-569e11af4667171da6dcb9cf20f6623a734a7e3c.tar.gz bcm5719-llvm-569e11af4667171da6dcb9cf20f6623a734a7e3c.zip |
ELF: Split Atoms.h to Atoms.{h,cpp}.
llvm-svn: 234935
-rw-r--r-- | lld/lib/ReaderWriter/ELF/Atoms.cpp | 319 | ||||
-rw-r--r-- | lld/lib/ReaderWriter/ELF/Atoms.h | 383 | ||||
-rw-r--r-- | lld/lib/ReaderWriter/ELF/CMakeLists.txt | 1 |
3 files changed, 342 insertions, 361 deletions
diff --git a/lld/lib/ReaderWriter/ELF/Atoms.cpp b/lld/lib/ReaderWriter/ELF/Atoms.cpp new file mode 100644 index 00000000000..839d91b71c4 --- /dev/null +++ b/lld/lib/ReaderWriter/ELF/Atoms.cpp @@ -0,0 +1,319 @@ +//===- lib/ReaderWriter/ELF/Atoms.cpp -------------------------------------===// +// +// The LLVM Linker +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "Atoms.h" +#include "DynamicFile.h" +#include "ELFFile.h" +#include "TargetHandler.h" + +namespace lld { +namespace elf { + +template <class ELFT> AbsoluteAtom::Scope ELFAbsoluteAtom<ELFT>::scope() const { + if (_symbol->getVisibility() == llvm::ELF::STV_HIDDEN) + return scopeLinkageUnit; + if (_symbol->getBinding() == llvm::ELF::STB_LOCAL) + return scopeTranslationUnit; + return scopeGlobal; +} + +template <class ELFT> +UndefinedAtom::CanBeNull ELFUndefinedAtom<ELFT>::canBeNull() const { + if (_symbol->getBinding() == llvm::ELF::STB_WEAK) + return CanBeNull::canBeNullAtBuildtime; + return CanBeNull::canBeNullNever; +} + +template <class ELFT> uint64_t ELFDefinedAtom<ELFT>::size() const { + // Common symbols are not allocated in object files, + // so use st_size to tell how many bytes are required. + if (_symbol && (_symbol->getType() == llvm::ELF::STT_COMMON || + _symbol->st_shndx == llvm::ELF::SHN_COMMON)) + return (uint64_t)_symbol->st_size; + + return _contentData.size(); +} + +template <class ELFT> AbsoluteAtom::Scope ELFDefinedAtom<ELFT>::scope() const { + if (!_symbol) + return scopeGlobal; + if (_symbol->getVisibility() == llvm::ELF::STV_HIDDEN) + return scopeLinkageUnit; + if (_symbol->getBinding() != llvm::ELF::STB_LOCAL) + return scopeGlobal; + return scopeTranslationUnit; +} + +template <class ELFT> DefinedAtom::Merge ELFDefinedAtom<ELFT>::merge() const { + if (!_symbol) + return mergeNo; + if (_symbol->getBinding() == llvm::ELF::STB_WEAK) + return mergeAsWeak; + if (_symbol->getType() == llvm::ELF::STT_COMMON || + _symbol->st_shndx == llvm::ELF::SHN_COMMON) + return mergeAsTentative; + return mergeNo; +} + +template <class ELFT> +DefinedAtom::ContentType ELFDefinedAtom<ELFT>::contentType() const { + if (_contentType != typeUnknown) + return _contentType; + + ContentType ret = typeUnknown; + uint64_t flags = _section->sh_flags; + + if (_section->sh_type == llvm::ELF::SHT_GROUP) + return typeGroupComdat; + + if (!_symbol && _sectionName.startswith(".gnu.linkonce")) + return typeGnuLinkOnce; + + if (!(flags & llvm::ELF::SHF_ALLOC)) + return _contentType = typeNoAlloc; + + if (_section->sh_flags == + (llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE | llvm::ELF::SHF_TLS)) { + return _contentType = _section->sh_type == llvm::ELF::SHT_NOBITS + ? typeThreadZeroFill + : typeThreadData; + } + + if ((_section->sh_flags == llvm::ELF::SHF_ALLOC) && + (_section->sh_type == llvm::ELF::SHT_PROGBITS)) + return _contentType = typeConstant; + + if (_symbol->getType() == llvm::ELF::STT_GNU_IFUNC) + return _contentType = typeResolver; + + if (_symbol->st_shndx == llvm::ELF::SHN_COMMON) + return _contentType = typeZeroFill; + + switch (_section->sh_type) { + case llvm::ELF::SHT_PROGBITS: + flags &= ~llvm::ELF::SHF_ALLOC; + flags &= ~llvm::ELF::SHF_GROUP; + switch (flags) { + case llvm::ELF::SHF_EXECINSTR: + case (llvm::ELF::SHF_WRITE | llvm::ELF::SHF_EXECINSTR): + ret = typeCode; + break; + case llvm::ELF::SHF_WRITE: + ret = typeData; + break; + case (llvm::ELF::SHF_MERGE | llvm::ELF::SHF_STRINGS): + case llvm::ELF::SHF_STRINGS: + case llvm::ELF::SHF_MERGE: + ret = typeConstant; + break; + default: + ret = typeCode; + break; + } + break; + case llvm::ELF::SHT_NOTE: + flags &= ~llvm::ELF::SHF_ALLOC; + switch (flags) { + case llvm::ELF::SHF_WRITE: + ret = typeRWNote; + break; + default: + ret = typeRONote; + break; + } + break; + case llvm::ELF::SHT_NOBITS: + ret = typeZeroFill; + break; + case llvm::ELF::SHT_NULL: + if ((_symbol->getType() == llvm::ELF::STT_COMMON) || + _symbol->st_shndx == llvm::ELF::SHN_COMMON) + ret = typeZeroFill; + break; + case llvm::ELF::SHT_INIT_ARRAY: + case llvm::ELF::SHT_FINI_ARRAY: + ret = typeData; + break; + } + + return _contentType = ret; +} + +template <class ELFT> +DefinedAtom::Alignment ELFDefinedAtom<ELFT>::alignment() const { + if (!_symbol) + return 1; + + // Obtain proper value of st_value field. + const auto symValue = getSymbolValue(); + + // Unallocated common symbols specify their alignment constraints in + // st_value. + if ((_symbol->getType() == llvm::ELF::STT_COMMON) || + _symbol->st_shndx == llvm::ELF::SHN_COMMON) { + return symValue; + } + if (_section->sh_addralign == 0) { + // sh_addralign of 0 means no alignment + return Alignment(1, symValue); + } + return Alignment(_section->sh_addralign, symValue % _section->sh_addralign); +} + +// Do we have a choice for ELF? All symbols live in explicit sections. +template <class ELFT> +DefinedAtom::SectionChoice ELFDefinedAtom<ELFT>::sectionChoice() const { + switch (contentType()) { + case typeCode: + case typeData: + case typeZeroFill: + case typeThreadZeroFill: + case typeThreadData: + case typeConstant: + if ((_sectionName == ".text") || (_sectionName == ".data") || + (_sectionName == ".bss") || (_sectionName == ".rodata") || + (_sectionName == ".tdata") || (_sectionName == ".tbss")) + return sectionBasedOnContent; + default: + break; + } + return sectionCustomRequired; +} + +template <class ELFT> +StringRef ELFDefinedAtom<ELFT>::customSectionName() const { + if ((contentType() == typeZeroFill) || + (_symbol && _symbol->st_shndx == llvm::ELF::SHN_COMMON)) + return ".bss"; + return _sectionName; +} + +template <class ELFT> +DefinedAtom::ContentPermissions ELFDefinedAtom<ELFT>::permissions() const { + if (_permissions != permUnknown) + return _permissions; + + uint64_t flags = _section->sh_flags; + + if (!(flags & llvm::ELF::SHF_ALLOC)) + return _permissions = perm___; + + switch (_section->sh_type) { + // permRW_L is for sections modified by the runtime + // loader. + case llvm::ELF::SHT_REL: + case llvm::ELF::SHT_RELA: + return _permissions = permRW_L; + + case llvm::ELF::SHT_DYNAMIC: + case llvm::ELF::SHT_PROGBITS: + case llvm::ELF::SHT_NOTE: + flags &= ~llvm::ELF::SHF_ALLOC; + flags &= ~llvm::ELF::SHF_GROUP; + switch (flags) { + // Code + case llvm::ELF::SHF_EXECINSTR: + return _permissions = permR_X; + case (llvm::ELF::SHF_WRITE | llvm::ELF::SHF_EXECINSTR): + return _permissions = permRWX; + // Data + case llvm::ELF::SHF_WRITE: + return _permissions = permRW_; + // Strings + case llvm::ELF::SHF_MERGE: + case llvm::ELF::SHF_STRINGS: + return _permissions = permR__; + + default: + if (flags & llvm::ELF::SHF_WRITE) + return _permissions = permRW_; + return _permissions = permR__; + } + + case llvm::ELF::SHT_NOBITS: + return _permissions = permRW_; + + case llvm::ELF::SHT_INIT_ARRAY: + case llvm::ELF::SHT_FINI_ARRAY: + return _permissions = permRW_; + + default: + return _permissions = perm___; + } +} + +template <class ELFT> +DefinedAtom::reference_iterator ELFDefinedAtom<ELFT>::begin() const { + uintptr_t index = _referenceStartIndex; + const void *it = reinterpret_cast<const void *>(index); + return reference_iterator(*this, it); +} + +template <class ELFT> +DefinedAtom::reference_iterator ELFDefinedAtom<ELFT>::end() const { + uintptr_t index = _referenceEndIndex; + const void *it = reinterpret_cast<const void *>(index); + return reference_iterator(*this, it); +} + +template <class ELFT> +const Reference *ELFDefinedAtom<ELFT>::derefIterator(const void *It) const { + uintptr_t index = reinterpret_cast<uintptr_t>(It); + assert(index >= _referenceStartIndex); + assert(index < _referenceEndIndex); + return ((_referenceList)[index]); +} + +template <class ELFT> +void ELFDefinedAtom<ELFT>::incrementIterator(const void *&It) const { + uintptr_t index = reinterpret_cast<uintptr_t>(It); + ++index; + It = reinterpret_cast<const void *>(index); +} + +template <class ELFT> +void ELFDefinedAtom<ELFT>::addReference(ELFReference<ELFT> *reference) { + _referenceList.push_back(reference); + _referenceEndIndex = _referenceList.size(); +} + +template <class ELFT> AbsoluteAtom::Scope ELFDynamicAtom<ELFT>::scope() const { + if (_symbol->getVisibility() == llvm::ELF::STV_HIDDEN) + return scopeLinkageUnit; + if (_symbol->getBinding() != llvm::ELF::STB_LOCAL) + return scopeGlobal; + return scopeTranslationUnit; +} + +template <class ELFT> +SharedLibraryAtom::Type ELFDynamicAtom<ELFT>::type() const { + switch (_symbol->getType()) { + case llvm::ELF::STT_FUNC: + case llvm::ELF::STT_GNU_IFUNC: + return Type::Code; + case llvm::ELF::STT_OBJECT: + return Type::Data; + default: + return Type::Unknown; + } +} + +#define INSTANTIATE(klass) \ + template class klass<ELF32LE>; \ + template class klass<ELF32BE>; \ + template class klass<ELF64LE>; \ + template class klass<ELF64BE>; + +INSTANTIATE(ELFAbsoluteAtom); +INSTANTIATE(ELFDefinedAtom); +INSTANTIATE(ELFDynamicAtom); +INSTANTIATE(ELFUndefinedAtom); + +} // end namespace elf +} // end namespace lld diff --git a/lld/lib/ReaderWriter/ELF/Atoms.h b/lld/lib/ReaderWriter/ELF/Atoms.h index 2bf51c4b2f6..f09e9743bd0 100644 --- a/lld/lib/ReaderWriter/ELF/Atoms.h +++ b/lld/lib/ReaderWriter/ELF/Atoms.h @@ -89,17 +89,8 @@ public: : _owningFile(file), _name(name), _symbol(symbol), _value(value) {} const ELFFile<ELFT> &file() const override { return _owningFile; } - - Scope scope() const override { - if (_symbol->getVisibility() == llvm::ELF::STV_HIDDEN) - return scopeLinkageUnit; - if (_symbol->getBinding() == llvm::ELF::STB_LOCAL) - return scopeTranslationUnit; - return scopeGlobal; - } - + Scope scope() const override; StringRef name() const override { return _name; } - uint64_t value() const override { return _value; } private: @@ -119,16 +110,11 @@ public: : _owningFile(file), _name(name), _symbol(symbol) {} const File &file() const override { return _owningFile; } - StringRef name() const override { return _name; } // A symbol in ELF can be undefined at build time if the symbol is a undefined // weak symbol. - CanBeNull canBeNull() const override { - if (_symbol->getBinding() == llvm::ELF::STB_WEAK) - return CanBeNull::canBeNullAtBuildtime; - return CanBeNull::canBeNullNever; - } + CanBeNull canBeNull() const override; private: const File &_owningFile; @@ -157,269 +143,34 @@ public: ~ELFDefinedAtom() {} const ELFFile<ELFT> &file() const override { return _owningFile; } - StringRef name() const override { return _symbolName; } - uint64_t ordinal() const override { return _ordinal; } - const Elf_Sym *symbol() const { return _symbol; } - const Elf_Shdr *section() const { return _section; } - - uint64_t size() const override { - // Common symbols are not allocated in object files, - // so use st_size to tell how many bytes are required. - if (_symbol && (_symbol->getType() == llvm::ELF::STT_COMMON || - _symbol->st_shndx == llvm::ELF::SHN_COMMON)) - return (uint64_t) _symbol->st_size; - - return _contentData.size(); - } - - Scope scope() const override { - if (!_symbol) - return scopeGlobal; - if (_symbol->getVisibility() == llvm::ELF::STV_HIDDEN) - return scopeLinkageUnit; - if (_symbol->getBinding() != llvm::ELF::STB_LOCAL) - return scopeGlobal; - return scopeTranslationUnit; - } + uint64_t size() const override; + Scope scope() const override; // FIXME: Need to revisit this in future. Interposable interposable() const override { return interposeNo; } - Merge merge() const override { - if (!_symbol) - return mergeNo; - - if (_symbol->getBinding() == llvm::ELF::STB_WEAK) - return mergeAsWeak; - - if ((_symbol->getType() == llvm::ELF::STT_COMMON) || - _symbol->st_shndx == llvm::ELF::SHN_COMMON) - return mergeAsTentative; - - return mergeNo; - } - - ContentType contentType() const override { - if (_contentType != typeUnknown) - return _contentType; - - ContentType ret = typeUnknown; - uint64_t flags = _section->sh_flags; - - if (_section->sh_type == llvm::ELF::SHT_GROUP) - return typeGroupComdat; - - if (!_symbol && _sectionName.startswith(".gnu.linkonce")) - return typeGnuLinkOnce; - - if (!(flags & llvm::ELF::SHF_ALLOC)) - return _contentType = typeNoAlloc; - - if (_section->sh_flags == - (llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE | llvm::ELF::SHF_TLS)) { - return _contentType = _section->sh_type == llvm::ELF::SHT_NOBITS ? typeThreadZeroFill - : typeThreadData; - } - - if ((_section->sh_flags == llvm::ELF::SHF_ALLOC) && - (_section->sh_type == llvm::ELF::SHT_PROGBITS)) - return _contentType = typeConstant; - - if (_symbol->getType() == llvm::ELF::STT_GNU_IFUNC) - return _contentType = typeResolver; - - if (_symbol->st_shndx == llvm::ELF::SHN_COMMON) - return _contentType = typeZeroFill; - - switch (_section->sh_type) { - case llvm::ELF::SHT_PROGBITS: - flags &= ~llvm::ELF::SHF_ALLOC; - flags &= ~llvm::ELF::SHF_GROUP; - switch (flags) { - case llvm::ELF::SHF_EXECINSTR: - case (llvm::ELF::SHF_WRITE|llvm::ELF::SHF_EXECINSTR): - ret = typeCode; - break; - case llvm::ELF::SHF_WRITE: - ret = typeData; - break; - case (llvm::ELF::SHF_MERGE|llvm::ELF::SHF_STRINGS): - case llvm::ELF::SHF_STRINGS: - case llvm::ELF::SHF_MERGE: - ret = typeConstant; - break; - default: - ret = typeCode; - break; - } - break; - case llvm::ELF::SHT_NOTE: - flags &= ~llvm::ELF::SHF_ALLOC; - switch (flags) { - case llvm::ELF::SHF_WRITE: - ret = typeRWNote; - break; - default: - ret = typeRONote; - break; - } - break; - case llvm::ELF::SHT_NOBITS: - ret = typeZeroFill; - break; - case llvm::ELF::SHT_NULL: - if ((_symbol->getType() == llvm::ELF::STT_COMMON) - || _symbol->st_shndx == llvm::ELF::SHN_COMMON) - ret = typeZeroFill; - break; - case llvm::ELF::SHT_INIT_ARRAY: - case llvm::ELF::SHT_FINI_ARRAY: - ret = typeData; - break; - } - - return _contentType = ret; - } - - Alignment alignment() const override { - if (!_symbol) - return 1; - - // Obtain proper value of st_value field. - const auto symValue = getSymbolValue(); - - // Unallocated common symbols specify their alignment constraints in - // st_value. - if ((_symbol->getType() == llvm::ELF::STT_COMMON) || - _symbol->st_shndx == llvm::ELF::SHN_COMMON) { - return symValue; - } - if (_section->sh_addralign == 0) { - // sh_addralign of 0 means no alignment - return Alignment(1, symValue); - } - return Alignment(_section->sh_addralign, - symValue % _section->sh_addralign); - } - - // Do we have a choice for ELF? All symbols live in explicit sections. - SectionChoice sectionChoice() const override { - switch (contentType()) { - case typeCode: - case typeData: - case typeZeroFill: - case typeThreadZeroFill: - case typeThreadData: - case typeConstant: - if ((_sectionName == ".text") || (_sectionName == ".data") || - (_sectionName == ".bss") || (_sectionName == ".rodata") || - (_sectionName == ".tdata") || (_sectionName == ".tbss")) - return sectionBasedOnContent; - default: - break; - } - return sectionCustomRequired; - } - - StringRef customSectionName() const override { - if ((contentType() == typeZeroFill) || - (_symbol && _symbol->st_shndx == llvm::ELF::SHN_COMMON)) - return ".bss"; - return _sectionName; - } + Merge merge() const override; + ContentType contentType() const override; + Alignment alignment() const override; + SectionChoice sectionChoice() const override; + StringRef customSectionName() const override; // It isn't clear that __attribute__((used)) is transmitted to the ELF object // file. DeadStripKind deadStrip() const override { return deadStripNormal; } - ContentPermissions permissions() const override { - if (_permissions != permUnknown) - return _permissions; - - uint64_t flags = _section->sh_flags; - - if (!(flags & llvm::ELF::SHF_ALLOC)) - return _permissions = perm___; - - switch (_section->sh_type) { - // permRW_L is for sections modified by the runtime - // loader. - case llvm::ELF::SHT_REL: - case llvm::ELF::SHT_RELA: - return _permissions = permRW_L; - - case llvm::ELF::SHT_DYNAMIC: - case llvm::ELF::SHT_PROGBITS: - case llvm::ELF::SHT_NOTE: - flags &= ~llvm::ELF::SHF_ALLOC; - flags &= ~llvm::ELF::SHF_GROUP; - switch (flags) { - // Code - case llvm::ELF::SHF_EXECINSTR: - return _permissions = permR_X; - case (llvm::ELF::SHF_WRITE|llvm::ELF::SHF_EXECINSTR): - return _permissions = permRWX; - // Data - case llvm::ELF::SHF_WRITE: - return _permissions = permRW_; - // Strings - case llvm::ELF::SHF_MERGE: - case llvm::ELF::SHF_STRINGS: - return _permissions = permR__; - - default: - if (flags & llvm::ELF::SHF_WRITE) - return _permissions = permRW_; - return _permissions = permR__; - } - - case llvm::ELF::SHT_NOBITS: - return _permissions = permRW_; - - case llvm::ELF::SHT_INIT_ARRAY: - case llvm::ELF::SHT_FINI_ARRAY: - return _permissions = permRW_; - - default: - return _permissions = perm___; - } - } - + ContentPermissions permissions() const override; ArrayRef<uint8_t> rawContent() const override { return _contentData; } - DefinedAtom::reference_iterator begin() const override { - uintptr_t index = _referenceStartIndex; - const void *it = reinterpret_cast<const void*>(index); - return reference_iterator(*this, it); - } - - DefinedAtom::reference_iterator end() const override { - uintptr_t index = _referenceEndIndex; - const void *it = reinterpret_cast<const void*>(index); - return reference_iterator(*this, it); - } - - const Reference *derefIterator(const void *It) const override { - uintptr_t index = reinterpret_cast<uintptr_t>(It); - assert(index >= _referenceStartIndex); - assert(index < _referenceEndIndex); - return ((_referenceList)[index]); - } - - void incrementIterator(const void *&It) const override { - uintptr_t index = reinterpret_cast<uintptr_t>(It); - ++index; - It = reinterpret_cast<const void *>(index); - } - - void addReference(ELFReference<ELFT> *reference) { - _referenceList.push_back(reference); - _referenceEndIndex = _referenceList.size(); - } + DefinedAtom::reference_iterator begin() const override; + DefinedAtom::reference_iterator end() const override; + const Reference *derefIterator(const void *It) const override; + void incrementIterator(const void *&It) const override; + void addReference(ELFReference<ELFT> *reference); virtual void setOrdinal(uint64_t ord) { _ordinal = ord; } @@ -460,25 +211,15 @@ public: } const ELFFile<ELFT> &file() const override { return _owningFile; } - StringRef name() const override { return ""; } - virtual uint64_t section() const { return _section->sh_name; } - virtual uint64_t offset() const { return _offset; } - virtual void setOrdinal(uint64_t ord) { _ordinal = ord; } - uint64_t ordinal() const override { return _ordinal; } - uint64_t size() const override { return _contentData.size(); } - Scope scope() const override { return scopeTranslationUnit; } - Interposable interposable() const override { return interposeNo; } - Merge merge() const override { return mergeByContent; } - ContentType contentType() const override { return typeConstant; } Alignment alignment() const override { @@ -486,13 +227,9 @@ public: } SectionChoice sectionChoice() const override { return sectionCustomRequired; } - StringRef customSectionName() const override { return _sectionName; } - DeadStripKind deadStrip() const override { return deadStripNormal; } - ContentPermissions permissions() const override { return permR__; } - ArrayRef<uint8_t> rawContent() const override { return _contentData; } DefinedAtom::reference_iterator begin() const override { @@ -514,7 +251,6 @@ public: void incrementIterator(const void *&It) const override {} private: - const ELFFile<ELFT> &_owningFile; StringRef _sectionName; const Elf_Shdr *_section; @@ -527,21 +263,14 @@ private: template <class ELFT> class ELFCommonAtom : public DefinedAtom { typedef llvm::object::Elf_Sym_Impl<ELFT> Elf_Sym; public: - ELFCommonAtom(const ELFFile<ELFT> &file, - StringRef symbolName, + ELFCommonAtom(const ELFFile<ELFT> &file, StringRef symbolName, const Elf_Sym *symbol) - : _owningFile(file), - _symbolName(symbolName), - _symbol(symbol) {} + : _owningFile(file), _symbolName(symbolName), _symbol(symbol) {} const ELFFile<ELFT> &file() const override { return _owningFile; } - StringRef name() const override { return _symbolName; } - uint64_t ordinal() const override { return _ordinal; } - virtual void setOrdinal(uint64_t ord) { _ordinal = ord; } - uint64_t size() const override { return _symbol->st_size; } Scope scope() const override { @@ -553,21 +282,13 @@ public: } Interposable interposable() const override { return interposeNo; } - Merge merge() const override { return mergeAsTentative; } - ContentType contentType() const override { return typeZeroFill; } - Alignment alignment() const override { return Alignment(_symbol->st_value); } - SectionChoice sectionChoice() const override { return sectionBasedOnContent; } - StringRef customSectionName() const override { return ".bss"; } - DeadStripKind deadStrip() const override { return deadStripNormal; } - ContentPermissions permissions() const override { return permRW_; } - ArrayRef<uint8_t> rawContent() const override { return ArrayRef<uint8_t>(); } DefinedAtom::reference_iterator begin() const override { @@ -603,42 +324,19 @@ public: ELFDynamicAtom(const DynamicFile<ELFT> &file, StringRef symbolName, StringRef loadName, const Elf_Sym *symbol) : _owningFile(file), _symbolName(symbolName), _loadName(loadName), - _symbol(symbol) { - } + _symbol(symbol) {} const DynamicFile<ELFT> &file() const override { return _owningFile; } - StringRef name() const override { return _symbolName; } - - virtual Scope scope() const { - if (_symbol->getVisibility() == llvm::ELF::STV_HIDDEN) - return scopeLinkageUnit; - if (_symbol->getBinding() != llvm::ELF::STB_LOCAL) - return scopeGlobal; - return scopeTranslationUnit; - } - + virtual Scope scope() const; StringRef loadName() const override { return _loadName; } bool canBeNullAtRuntime() const override { return _symbol->getBinding() == llvm::ELF::STB_WEAK; } - Type type() const override { - switch (_symbol->getType()) { - case llvm::ELF::STT_FUNC: - case llvm::ELF::STT_GNU_IFUNC: - return Type::Code; - case llvm::ELF::STT_OBJECT: - return Type::Data; - default: - return Type::Unknown; - } - } - - uint64_t size() const override { - return _symbol->st_size; - } + Type type() const override; + uint64_t size() const override { return _symbol->st_size; } private: @@ -688,23 +386,14 @@ public: class ObjectAtom : public SimpleELFDefinedAtom { public: ObjectAtom(const File &f) : SimpleELFDefinedAtom(f) {} - Scope scope() const override { return scopeGlobal; } - SectionChoice sectionChoice() const override { return sectionBasedOnContent; } - ContentType contentType() const override { return typeZeroFill; } - uint64_t size() const override { return _size; } - DynamicExport dynamicExport() const override { return dynamicExportAlways; } - ContentPermissions permissions() const override { return permRW_; } - ArrayRef<uint8_t> rawContent() const override { return ArrayRef<uint8_t>(); } - Alignment alignment() const override { return 8; } - StringRef name() const override { return _name; } std::string _name; @@ -719,17 +408,11 @@ public: : SimpleELFDefinedAtom(f), _section(secName) {} Scope scope() const override { return scopeTranslationUnit; } - SectionChoice sectionChoice() const override { return sectionCustomRequired; } - StringRef customSectionName() const override { return _section; } - ContentType contentType() const override { return typeGOT; } - uint64_t size() const override { return rawContent().size(); } - ContentPermissions permissions() const override { return permRW_; } - Alignment alignment() const override { return 8; } #ifndef NDEBUG @@ -748,17 +431,11 @@ public: : SimpleELFDefinedAtom(f), _section(secName) {} Scope scope() const override { return scopeTranslationUnit; } - SectionChoice sectionChoice() const override { return sectionCustomRequired; } - StringRef customSectionName() const override { return _section; } - ContentType contentType() const override { return typeStub; } - uint64_t size() const override { return rawContent().size(); } - ContentPermissions permissions() const override { return permR_X; } - Alignment alignment() const override { return 16; } #ifndef NDEBUG @@ -783,21 +460,13 @@ public: GlobalOffsetTableAtom(const File &f) : SimpleELFDefinedAtom(f) {} StringRef name() const override { return "_GLOBAL_OFFSET_TABLE_"; } - Scope scope() const override { return scopeLinkageUnit; } - SectionChoice sectionChoice() const override { return sectionCustomRequired; } - StringRef customSectionName() const override { return ".got.plt"; } - ContentType contentType() const override { return typeGOT; } - uint64_t size() const override { return 0; } - ContentPermissions permissions() const override { return permRW_; } - Alignment alignment() const override { return 8; } - ArrayRef<uint8_t> rawContent() const override { return ArrayRef<uint8_t>(); } }; @@ -806,25 +475,17 @@ public: DynamicAtom(const File &f) : SimpleELFDefinedAtom(f) {} StringRef name() const override { return "_DYNAMIC"; } - Scope scope() const override { return scopeLinkageUnit; } - Merge merge() const override { return mergeNo; } - SectionChoice sectionChoice() const override { return sectionCustomRequired; } - StringRef customSectionName() const override { return ".dynamic"; } - ContentType contentType() const override { return typeData; } - uint64_t size() const override { return 0; } - ContentPermissions permissions() const override { return permRW_; } - Alignment alignment() const override { return 1; } - ArrayRef<uint8_t> rawContent() const override { return ArrayRef<uint8_t>(); } }; + } // end namespace elf } // end namespace lld diff --git a/lld/lib/ReaderWriter/ELF/CMakeLists.txt b/lld/lib/ReaderWriter/ELF/CMakeLists.txt index 958a59bd5e0..d70b5daedec 100644 --- a/lld/lib/ReaderWriter/ELF/CMakeLists.txt +++ b/lld/lib/ReaderWriter/ELF/CMakeLists.txt @@ -1,4 +1,5 @@ add_llvm_library(lldELF + Atoms.cpp DynamicFile.cpp ELFFile.cpp ELFLinkingContext.cpp |