diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2015-03-24 21:31:36 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2015-03-24 21:31:36 +0000 |
| commit | fb911942f1434f3d1750f83f25f5e42c80e60638 (patch) | |
| tree | 1678c4a4f0182e4029a86d135aa4a1b7d09e3c41 /lib/ReaderWriter/ELF/AArch64/AArch64LinkingContext.h | |
Notes
Diffstat (limited to 'lib/ReaderWriter/ELF/AArch64/AArch64LinkingContext.h')
| -rw-r--r-- | lib/ReaderWriter/ELF/AArch64/AArch64LinkingContext.h | 95 |
1 files changed, 95 insertions, 0 deletions
diff --git a/lib/ReaderWriter/ELF/AArch64/AArch64LinkingContext.h b/lib/ReaderWriter/ELF/AArch64/AArch64LinkingContext.h new file mode 100644 index 000000000000..ebd91fe0a95b --- /dev/null +++ b/lib/ReaderWriter/ELF/AArch64/AArch64LinkingContext.h @@ -0,0 +1,95 @@ +//===- lib/ReaderWriter/ELF/AArch64/AArch64LinkingContext.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_AARCH64_AARCH64_LINKING_CONTEXT_H +#define LLD_READER_WRITER_ELF_AARCH64_AARCH64_LINKING_CONTEXT_H + +#include "lld/ReaderWriter/ELFLinkingContext.h" +#include "llvm/Object/ELF.h" +#include "llvm/Support/ELF.h" + +namespace lld { +namespace elf { + +enum { + /// \brief The offset to add operation for a R_AARCH64_ADR_GOT_PAGE + ADD_AARCH64_GOTRELINDEX = 0xE000, +}; + +class AArch64LinkingContext final : public ELFLinkingContext { +public: + static std::unique_ptr<ELFLinkingContext> create(llvm::Triple); + AArch64LinkingContext(llvm::Triple); + + void addPasses(PassManager &) override; + + uint64_t getBaseAddress() const override { + if (_baseAddress == 0) + return 0x400000; + return _baseAddress; + } + + bool isDynamicRelocation(const Reference &r) const override { + if (r.kindNamespace() != Reference::KindNamespace::ELF) + return false; + assert(r.kindArch() == Reference::KindArch::AArch64); + switch (r.kindValue()) { + case llvm::ELF::R_AARCH64_COPY: + case llvm::ELF::R_AARCH64_GLOB_DAT: + case llvm::ELF::R_AARCH64_RELATIVE: + case llvm::ELF::R_AARCH64_TLS_DTPREL64: + case llvm::ELF::R_AARCH64_TLS_DTPMOD64: + case llvm::ELF::R_AARCH64_TLS_TPREL64: + case llvm::ELF::R_AARCH64_TLSDESC: + case llvm::ELF::R_AARCH64_IRELATIVE: + return true; + default: + return false; + } + } + + bool isCopyRelocation(const Reference &r) const override { + if (r.kindNamespace() != Reference::KindNamespace::ELF) + return false; + assert(r.kindArch() == Reference::KindArch::AArch64); + if (r.kindValue() == llvm::ELF::R_AARCH64_COPY) + return true; + return false; + } + + bool isPLTRelocation(const Reference &r) const override { + if (r.kindNamespace() != Reference::KindNamespace::ELF) + return false; + assert(r.kindArch() == Reference::KindArch::AArch64); + switch (r.kindValue()) { + case llvm::ELF::R_AARCH64_JUMP_SLOT: + case llvm::ELF::R_AARCH64_IRELATIVE: + return true; + default: + return false; + } + } + + bool isRelativeReloc(const Reference &r) const override { + if (r.kindNamespace() != Reference::KindNamespace::ELF) + return false; + assert(r.kindArch() == Reference::KindArch::AArch64); + switch (r.kindValue()) { + case llvm::ELF::R_AARCH64_IRELATIVE: + case llvm::ELF::R_AARCH64_RELATIVE: + return true; + default: + return false; + } + } +}; +} // end namespace elf +} // end namespace lld + +#endif |
