aboutsummaryrefslogtreecommitdiff
path: root/lib/ReaderWriter/ELF/Atoms.h
diff options
context:
space:
mode:
Diffstat (limited to 'lib/ReaderWriter/ELF/Atoms.h')
-rw-r--r--lib/ReaderWriter/ELF/Atoms.h493
1 files changed, 0 insertions, 493 deletions
diff --git a/lib/ReaderWriter/ELF/Atoms.h b/lib/ReaderWriter/ELF/Atoms.h
deleted file mode 100644
index 390c0e16baf8..000000000000
--- a/lib/ReaderWriter/ELF/Atoms.h
+++ /dev/null
@@ -1,493 +0,0 @@
-//===- lib/ReaderWriter/ELF/Atoms.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_ATOMS_H
-#define LLD_READER_WRITER_ELF_ATOMS_H
-
-#include "TargetHandler.h"
-#include "lld/Core/LLVM.h"
-#include "lld/Core/Simple.h"
-#include "lld/ReaderWriter/ELFLinkingContext.h"
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/StringSwitch.h"
-#include <memory>
-#include <vector>
-
-namespace lld {
-namespace elf {
-template <class ELFT> class DynamicFile;
-template <typename ELFT> class ELFFile;
-
-/// \brief Relocation References: Defined Atoms may contain references that will
-/// need to be patched before the executable is written.
-///
-/// Construction of ELFReferences is two pass process. ELFReferences are
-/// instantiated while we are iterating over symbol tables to atomize
-/// symbols. At that time we only know the index of relocation target symbol
-/// (not target atom) about a relocation, so we store the index to
-/// ELFREference. In the second pass, ELFReferences are revisited to update
-/// target atoms by target symbol indexes.
-template <class ELFT> class ELFReference : public Reference {
- typedef llvm::object::Elf_Rel_Impl<ELFT, false> Elf_Rel;
- typedef llvm::object::Elf_Rel_Impl<ELFT, true> Elf_Rela;
- typedef llvm::object::Elf_Sym_Impl<ELFT> Elf_Sym;
-
-public:
- ELFReference(const Elf_Rela *rela, uint64_t off, Reference::KindArch arch,
- Reference::KindValue relocType, uint32_t idx)
- : Reference(Reference::KindNamespace::ELF, arch, relocType),
- _targetSymbolIndex(idx), _offsetInAtom(off), _addend(rela->r_addend) {}
-
- ELFReference(uint64_t off, Reference::KindArch arch,
- Reference::KindValue relocType, uint32_t idx)
- : Reference(Reference::KindNamespace::ELF, arch, relocType),
- _targetSymbolIndex(idx), _offsetInAtom(off) {}
-
- ELFReference(uint32_t edgeKind)
- : Reference(Reference::KindNamespace::all, Reference::KindArch::all,
- edgeKind) {}
-
- uint64_t offsetInAtom() const override { return _offsetInAtom; }
-
- const Atom *target() const override { return _target; }
-
- /// \brief The symbol table index that contains the target reference.
- uint64_t targetSymbolIndex() const {
- return _targetSymbolIndex;
- }
-
- Addend addend() const override { return _addend; }
-
- virtual void setOffset(uint64_t off) { _offsetInAtom = off; }
-
- void setAddend(Addend A) override { _addend = A; }
-
- void setTarget(const Atom *newAtom) override { _target = newAtom; }
-
-private:
- const Atom *_target = nullptr;
- uint64_t _targetSymbolIndex = 0;
- uint64_t _offsetInAtom = 0;
- Addend _addend = 0;
-};
-
-/// \brief These atoms store symbols that are fixed to a particular address.
-/// This atom has no content its address will be used by the writer to fixup
-/// references that point to it.
-template <class ELFT> class ELFAbsoluteAtom : public AbsoluteAtom {
- typedef llvm::object::Elf_Sym_Impl<ELFT> Elf_Sym;
-
-public:
- ELFAbsoluteAtom(const ELFFile<ELFT> &file, StringRef name,
- const Elf_Sym *symbol, uint64_t value)
- : _owningFile(file), _name(name), _symbol(symbol), _value(value) {}
-
- const ELFFile<ELFT> &file() const override { return _owningFile; }
- Scope scope() const override;
- StringRef name() const override { return _name; }
- uint64_t value() const override { return _value; }
-
-private:
- const ELFFile<ELFT> &_owningFile;
- StringRef _name;
- const Elf_Sym *_symbol;
- uint64_t _value;
-};
-
-/// \brief ELFUndefinedAtom: These atoms store undefined symbols and are place
-/// holders that will be replaced by defined atoms later in the linking process.
-template <class ELFT> class ELFUndefinedAtom : public UndefinedAtom {
- typedef llvm::object::Elf_Sym_Impl<ELFT> Elf_Sym;
-
-public:
- ELFUndefinedAtom(const File &file, StringRef name, const Elf_Sym *symbol)
- : _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;
-
-private:
- const File &_owningFile;
- StringRef _name;
- const Elf_Sym *_symbol;
-};
-
-/// \brief This atom stores defined symbols and will contain either data or
-/// code.
-template <class ELFT> class ELFDefinedAtom : public DefinedAtom {
- typedef llvm::object::Elf_Sym_Impl<ELFT> Elf_Sym;
- typedef llvm::object::Elf_Shdr_Impl<ELFT> Elf_Shdr;
-
-public:
- ELFDefinedAtom(const ELFFile<ELFT> &file, StringRef symbolName,
- StringRef sectionName, const Elf_Sym *symbol,
- const Elf_Shdr *section, ArrayRef<uint8_t> contentData,
- unsigned int referenceStart, unsigned int referenceEnd,
- std::vector<ELFReference<ELFT> *> &referenceList)
- : _owningFile(file), _symbolName(symbolName), _sectionName(sectionName),
- _symbol(symbol), _section(section), _contentData(contentData),
- _referenceStartIndex(referenceStart), _referenceEndIndex(referenceEnd),
- _referenceList(referenceList), _contentType(typeUnknown),
- _permissions(permUnknown) {}
-
- ~ELFDefinedAtom() override = default;
-
- 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;
- Scope scope() const override;
-
- // FIXME: Need to revisit this in future.
- Interposable interposable() const override { return interposeNo; }
-
- 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;
- ArrayRef<uint8_t> rawContent() const override { return _contentData; }
-
- 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; }
-
-protected:
- /// Returns correct st_value for the symbol depending on the architecture.
- /// For most architectures it's just a regular st_value with no changes.
- virtual uint64_t getSymbolValue() const {
- return _symbol->st_value;
- }
-
- ContentType doContentType() const;
-
- const ELFFile<ELFT> &_owningFile;
- StringRef _symbolName;
- StringRef _sectionName;
- const Elf_Sym *_symbol;
- const Elf_Shdr *_section;
- /// \brief Holds the bits that make up the atom.
- ArrayRef<uint8_t> _contentData;
-
- uint64_t _ordinal;
- unsigned int _referenceStartIndex;
- unsigned int _referenceEndIndex;
- std::vector<ELFReference<ELFT> *> &_referenceList;
- mutable ContentType _contentType;
- mutable ContentPermissions _permissions;
-};
-
-/// \brief This atom stores mergeable Strings
-template <class ELFT> class ELFMergeAtom : public DefinedAtom {
- typedef llvm::object::Elf_Shdr_Impl<ELFT> Elf_Shdr;
-
-public:
- ELFMergeAtom(const ELFFile<ELFT> &file, StringRef sectionName,
- const Elf_Shdr *section, ArrayRef<uint8_t> contentData,
- uint64_t offset)
- : _owningFile(file), _sectionName(sectionName), _section(section),
- _contentData(contentData), _offset(offset) {
- }
-
- 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 {
- return Alignment(_section->sh_addralign);
- }
-
- 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 {
- uintptr_t index = 0;
- const void *it = reinterpret_cast<const void *>(index);
- return reference_iterator(*this, it);
- }
-
- DefinedAtom::reference_iterator end() const override {
- uintptr_t index = 0;
- const void *it = reinterpret_cast<const void *>(index);
- return reference_iterator(*this, it);
- }
-
- const Reference *derefIterator(const void *It) const override {
- return nullptr;
- }
-
- void incrementIterator(const void *&It) const override {}
-
-private:
- const ELFFile<ELFT> &_owningFile;
- StringRef _sectionName;
- const Elf_Shdr *_section;
- /// \brief Holds the bits that make up the atom.
- ArrayRef<uint8_t> _contentData;
- uint64_t _ordinal;
- uint64_t _offset;
-};
-
-template <class ELFT> class ELFCommonAtom : public DefinedAtom {
- typedef llvm::object::Elf_Sym_Impl<ELFT> Elf_Sym;
-public:
- ELFCommonAtom(const ELFFile<ELFT> &file, StringRef symbolName,
- const Elf_Sym *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 {
- if (_symbol->getVisibility() == llvm::ELF::STV_HIDDEN)
- return scopeLinkageUnit;
- if (_symbol->getBinding() != llvm::ELF::STB_LOCAL)
- return scopeGlobal;
- return scopeTranslationUnit;
- }
-
- 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 {
- uintptr_t index = 0;
- const void *it = reinterpret_cast<const void *>(index);
- return reference_iterator(*this, it);
- }
-
- DefinedAtom::reference_iterator end() const override {
- uintptr_t index = 0;
- const void *it = reinterpret_cast<const void *>(index);
- return reference_iterator(*this, it);
- }
-
-protected:
- const Reference *derefIterator(const void *iter) const override {
- return nullptr;
- }
-
- void incrementIterator(const void *&iter) const override {}
-
- const ELFFile<ELFT> &_owningFile;
- StringRef _symbolName;
- const Elf_Sym *_symbol;
- uint64_t _ordinal;
-};
-
-/// \brief An atom from a shared library.
-template <class ELFT> class ELFDynamicAtom : public SharedLibraryAtom {
- typedef llvm::object::Elf_Sym_Impl<ELFT> Elf_Sym;
-
-public:
- ELFDynamicAtom(const DynamicFile<ELFT> &file, StringRef symbolName,
- StringRef loadName, const Elf_Sym *symbol)
- : _owningFile(file), _symbolName(symbolName), _loadName(loadName),
- _symbol(symbol) {}
-
- const DynamicFile<ELFT> &file() const override { return _owningFile; }
- StringRef name() const override { return _symbolName; }
- 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;
- uint64_t size() const override { return _symbol->st_size; }
-
-private:
-
- const DynamicFile<ELFT> &_owningFile;
- StringRef _symbolName;
- StringRef _loadName;
- const Elf_Sym *_symbol;
-};
-
-class SimpleELFDefinedAtom : public SimpleDefinedAtom {
-public:
- SimpleELFDefinedAtom(const File &f) : SimpleDefinedAtom(f) {}
-
- void addReferenceELF(Reference::KindArch arch, Reference::KindValue kindValue,
- uint64_t off, const Atom *t, Reference::Addend a) {
- addReference(Reference::KindNamespace::ELF, arch, kindValue, off, t, a);
- }
-
- void addReferenceELF_Hexagon(Reference::KindValue relocType, uint64_t off,
- const Atom *t, Reference::Addend a) {
- addReferenceELF(Reference::KindArch::Hexagon, relocType, off, t, a);
- }
-
- void addReferenceELF_x86_64(Reference::KindValue relocType, uint64_t off,
- const Atom *t, Reference::Addend a) {
- addReferenceELF(Reference::KindArch::x86_64, relocType, off, t, a);
- }
-
- void addReferenceELF_Mips(Reference::KindValue relocType, uint64_t off,
- const Atom *t, Reference::Addend a) {
- addReferenceELF(Reference::KindArch::Mips, relocType, off, t, a);
- }
-
- void addReferenceELF_AArch64(Reference::KindValue relocType, uint64_t off,
- const Atom *t, Reference::Addend a) {
- addReferenceELF(Reference::KindArch::AArch64, relocType, off, t, a);
- }
-
- void addReferenceELF_ARM(Reference::KindValue relocType, uint64_t off,
- const Atom *t, Reference::Addend a) {
- addReferenceELF(Reference::KindArch::ARM, relocType, off, t, a);
- }
-};
-
-/// \brief Atom which represents an object for which a COPY relocation will be
-/// generated.
-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;
- uint64_t _size;
-};
-
-class GOTAtom : public SimpleELFDefinedAtom {
- StringRef _section;
-
-public:
- GOTAtom(const File &f, StringRef secName)
- : 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
- StringRef name() const override { return _name; }
- std::string _name;
-#else
- StringRef name() const override { return ""; }
-#endif
-};
-
-class PLTAtom : public SimpleELFDefinedAtom {
- StringRef _section;
-
-public:
- PLTAtom(const File &f, StringRef secName)
- : 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
- StringRef name() const override { return _name; }
- std::string _name;
-#else
- StringRef name() const override { return ""; }
-#endif
-};
-
-class PLT0Atom : public PLTAtom {
-public:
- PLT0Atom(const File &f) : PLTAtom(f, ".plt") {
-#ifndef NDEBUG
- _name = ".PLT0";
-#endif
- }
-};
-
-class GlobalOffsetTableAtom : public SimpleELFDefinedAtom {
-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>(); }
-};
-
-class DynamicAtom : public SimpleELFDefinedAtom {
-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
-
-#endif // LLD_READER_WRITER_ELF_ATOMS_H