diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2016-07-23 20:48:50 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2016-07-23 20:48:50 +0000 |
| commit | 1c98619801a5705c688e683be3ef9d70169a0686 (patch) | |
| tree | 8422105cd1a94c368315f2db16b9ac746cf7c000 /lib/ReaderWriter/ELF/AArch64 | |
| parent | f4f3ce4613680903220815690ad79fc7ba0a2e26 (diff) | |
Notes
Diffstat (limited to 'lib/ReaderWriter/ELF/AArch64')
| -rw-r--r-- | lib/ReaderWriter/ELF/AArch64/AArch64DynamicLibraryWriter.h | 45 | ||||
| -rw-r--r-- | lib/ReaderWriter/ELF/AArch64/AArch64ExecutableWriter.cpp | 52 | ||||
| -rw-r--r-- | lib/ReaderWriter/ELF/AArch64/AArch64ExecutableWriter.h | 38 | ||||
| -rw-r--r-- | lib/ReaderWriter/ELF/AArch64/AArch64LinkingContext.cpp | 45 | ||||
| -rw-r--r-- | lib/ReaderWriter/ELF/AArch64/AArch64LinkingContext.h | 101 | ||||
| -rw-r--r-- | lib/ReaderWriter/ELF/AArch64/AArch64RelocationHandler.cpp | 556 | ||||
| -rw-r--r-- | lib/ReaderWriter/ELF/AArch64/AArch64RelocationHandler.h | 36 | ||||
| -rw-r--r-- | lib/ReaderWriter/ELF/AArch64/AArch64RelocationPass.cpp | 612 | ||||
| -rw-r--r-- | lib/ReaderWriter/ELF/AArch64/AArch64RelocationPass.h | 32 | ||||
| -rw-r--r-- | lib/ReaderWriter/ELF/AArch64/AArch64SectionChunks.cpp | 39 | ||||
| -rw-r--r-- | lib/ReaderWriter/ELF/AArch64/AArch64SectionChunks.h | 37 | ||||
| -rw-r--r-- | lib/ReaderWriter/ELF/AArch64/AArch64TargetHandler.cpp | 51 | ||||
| -rw-r--r-- | lib/ReaderWriter/ELF/AArch64/AArch64TargetHandler.h | 90 | ||||
| -rw-r--r-- | lib/ReaderWriter/ELF/AArch64/CMakeLists.txt | 14 | ||||
| -rw-r--r-- | lib/ReaderWriter/ELF/AArch64/TODO.rst | 15 |
15 files changed, 0 insertions, 1763 deletions
diff --git a/lib/ReaderWriter/ELF/AArch64/AArch64DynamicLibraryWriter.h b/lib/ReaderWriter/ELF/AArch64/AArch64DynamicLibraryWriter.h deleted file mode 100644 index 73864d2b4c38..000000000000 --- a/lib/ReaderWriter/ELF/AArch64/AArch64DynamicLibraryWriter.h +++ /dev/null @@ -1,45 +0,0 @@ -//===- lib/ReaderWriter/ELF/AArch64/AArch64DynamicLibraryWriter.h ---------===// -// -// The LLVM Linker -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -#ifndef AARCH64_DYNAMIC_LIBRARY_WRITER_H -#define AARCH64_DYNAMIC_LIBRARY_WRITER_H - -#include "AArch64LinkingContext.h" -#include "AArch64TargetHandler.h" -#include "DynamicLibraryWriter.h" - -namespace lld { -namespace elf { - -class AArch64DynamicLibraryWriter : public DynamicLibraryWriter<ELF64LE> { -public: - AArch64DynamicLibraryWriter(AArch64LinkingContext &ctx, - TargetLayout<ELF64LE> &layout); - -protected: - // Add any runtime files and their atoms to the output - void createImplicitFiles(std::vector<std::unique_ptr<File>> &) override; -}; - -AArch64DynamicLibraryWriter::AArch64DynamicLibraryWriter( - AArch64LinkingContext &ctx, TargetLayout<ELF64LE> &layout) - : DynamicLibraryWriter(ctx, layout) {} - -void AArch64DynamicLibraryWriter::createImplicitFiles( - std::vector<std::unique_ptr<File>> &result) { - DynamicLibraryWriter::createImplicitFiles(result); - auto gotFile = llvm::make_unique<SimpleFile>("GOTFile"); - gotFile->addAtom(*new (gotFile->allocator()) GlobalOffsetTableAtom(*gotFile)); - gotFile->addAtom(*new (gotFile->allocator()) DynamicAtom(*gotFile)); - result.push_back(std::move(gotFile)); -} - -} // namespace elf -} // namespace lld - -#endif diff --git a/lib/ReaderWriter/ELF/AArch64/AArch64ExecutableWriter.cpp b/lib/ReaderWriter/ELF/AArch64/AArch64ExecutableWriter.cpp deleted file mode 100644 index 9a9ec6cba12b..000000000000 --- a/lib/ReaderWriter/ELF/AArch64/AArch64ExecutableWriter.cpp +++ /dev/null @@ -1,52 +0,0 @@ -//===- lib/ReaderWriter/ELF/AArch64/AArch64ExecutableWriter.cpp -------------===// -// -// The LLVM Linker -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "AArch64LinkingContext.h" -#include "AArch64ExecutableWriter.h" -#include "AArch64TargetHandler.h" -#include "AArch64SectionChunks.h" - -namespace lld { -namespace elf { - -AArch64ExecutableWriter::AArch64ExecutableWriter(AArch64LinkingContext &ctx, - AArch64TargetLayout &layout) - : ExecutableWriter(ctx, layout), _targetLayout(layout) {} - -void AArch64ExecutableWriter::createImplicitFiles( - std::vector<std::unique_ptr<File>> &result) { - ExecutableWriter::createImplicitFiles(result); - auto gotFile = llvm::make_unique<SimpleFile>("GOTFile"); - gotFile->addAtom(*new (gotFile->allocator()) GlobalOffsetTableAtom(*gotFile)); - if (this->_ctx.isDynamic()) - gotFile->addAtom(*new (gotFile->allocator()) DynamicAtom(*gotFile)); - result.push_back(std::move(gotFile)); -} - -void AArch64ExecutableWriter::buildDynamicSymbolTable(const File &file) { - for (auto sec : this->_layout.sections()) { - if (auto section = dyn_cast<AtomSection<ELF64LE>>(sec)) { - for (const auto &atom : section->atoms()) { - // Add all globals GOT symbols (in both .got and .got.plt sections) - // on dynamic symbol table. - for (const auto §ion : _targetLayout.getGOTSections()) { - if (section->hasGlobalGOTEntry(atom->_atom)) - _dynamicSymbolTable->addSymbol(atom->_atom, section->ordinal(), - atom->_virtualAddr, atom); - } - } - } - } - - ExecutableWriter<ELF64LE>::buildDynamicSymbolTable(file); -} - -} // namespace elf -} // namespace lld - diff --git a/lib/ReaderWriter/ELF/AArch64/AArch64ExecutableWriter.h b/lib/ReaderWriter/ELF/AArch64/AArch64ExecutableWriter.h deleted file mode 100644 index eef825040ffa..000000000000 --- a/lib/ReaderWriter/ELF/AArch64/AArch64ExecutableWriter.h +++ /dev/null @@ -1,38 +0,0 @@ -//===- lib/ReaderWriter/ELF/AArch64/AArch64ExecutableWriter.h -------------===// -// -// The LLVM Linker -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -#ifndef AARCH64_EXECUTABLE_WRITER_H -#define AARCH64_EXECUTABLE_WRITER_H - -#include "ExecutableWriter.h" - -namespace lld { -namespace elf { - -class AArch64TargetLayout; -class AArch64LinkingContext; - -class AArch64ExecutableWriter : public ExecutableWriter<ELF64LE> { -public: - AArch64ExecutableWriter(AArch64LinkingContext &ctx, - AArch64TargetLayout &layout); - -protected: - // Add any runtime files and their atoms to the output - void createImplicitFiles(std::vector<std::unique_ptr<File>> &) override; - - void buildDynamicSymbolTable(const File &file) override; - -private: - AArch64TargetLayout &_targetLayout; -}; - -} // namespace elf -} // namespace lld - -#endif diff --git a/lib/ReaderWriter/ELF/AArch64/AArch64LinkingContext.cpp b/lib/ReaderWriter/ELF/AArch64/AArch64LinkingContext.cpp deleted file mode 100644 index ba883f7f59db..000000000000 --- a/lib/ReaderWriter/ELF/AArch64/AArch64LinkingContext.cpp +++ /dev/null @@ -1,45 +0,0 @@ -//===- lib/ReaderWriter/ELF/AArch64/AArch64LinkingContext.cpp -------------===// -// -// The LLVM Linker -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "AArch64LinkingContext.h" -#include "AArch64RelocationPass.h" -#include "AArch64TargetHandler.h" - -using namespace lld; -using namespace lld::elf; - -std::unique_ptr<ELFLinkingContext> -elf::createAArch64LinkingContext(llvm::Triple triple) { - if (triple.getArch() == llvm::Triple::aarch64) - return llvm::make_unique<AArch64LinkingContext>(triple); - return nullptr; -} - -AArch64LinkingContext::AArch64LinkingContext(llvm::Triple triple) - : ELFLinkingContext(triple, std::unique_ptr<TargetHandler>( - new AArch64TargetHandler(*this))) {} - -void AArch64LinkingContext::addPasses(PassManager &pm) { - auto pass = createAArch64RelocationPass(*this); - if (pass) - pm.add(std::move(pass)); - ELFLinkingContext::addPasses(pm); -} - -static const Registry::KindStrings kindStrings[] = { -#define ELF_RELOC(name, value) LLD_KIND_STRING_ENTRY(name), -#include "llvm/Support/ELFRelocs/AArch64.def" -#undef ELF_RELOC - LLD_KIND_STRING_END -}; - -void AArch64LinkingContext::registerRelocationNames(Registry ®istry) { - registry.addKindTable(Reference::KindNamespace::ELF, - Reference::KindArch::AArch64, kindStrings); -} diff --git a/lib/ReaderWriter/ELF/AArch64/AArch64LinkingContext.h b/lib/ReaderWriter/ELF/AArch64/AArch64LinkingContext.h deleted file mode 100644 index 25a173158318..000000000000 --- a/lib/ReaderWriter/ELF/AArch64/AArch64LinkingContext.h +++ /dev/null @@ -1,101 +0,0 @@ -//===- 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: - int getMachineType() const override { return llvm::ELF::EM_AARCH64; } - AArch64LinkingContext(llvm::Triple); - - void addPasses(PassManager &) override; - void registerRelocationNames(Registry &r) 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; - } - } - - /// \brief The path to the dynamic interpreter - StringRef getDefaultInterpreter() const override { - return "/lib/ld-linux-aarch64.so.1"; - } -}; -} // end namespace elf -} // end namespace lld - -#endif diff --git a/lib/ReaderWriter/ELF/AArch64/AArch64RelocationHandler.cpp b/lib/ReaderWriter/ELF/AArch64/AArch64RelocationHandler.cpp deleted file mode 100644 index ac7c769ec26d..000000000000 --- a/lib/ReaderWriter/ELF/AArch64/AArch64RelocationHandler.cpp +++ /dev/null @@ -1,556 +0,0 @@ -//===- lib/ReaderWriter/ELF/AArch64/AArch64RelocationHandler.cpp ----------===// -// -// The LLVM Linker -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "AArch64TargetHandler.h" -#include "AArch64LinkingContext.h" -#include "llvm/Support/Debug.h" -#include "llvm/Support/Endian.h" -#include "llvm/Support/MathExtras.h" - -#define DEBUG_TYPE "AArch64" - -using namespace lld; -using namespace lld::elf; -using namespace llvm; -using namespace llvm::support::endian; - -static int64_t page(int64_t v) { return v & ~int64_t(0xFFF); } - -/// \brief Check X is in the interval (-2^(bits-1), 2^bits] -static bool withinSignedUnsignedRange(int64_t X, int bits) { - return isIntN(bits - 1, X) || isUIntN(bits, X); -} - -/// \brief R_AARCH64_ABS64 - word64: S + A -static void relocR_AARCH64_ABS64(uint8_t *location, uint64_t P, uint64_t S, - int64_t A) { - int64_t result = (int64_t)S + A; - DEBUG(llvm::dbgs() << "\t\tHandle " << LLVM_FUNCTION_NAME << " -"; - llvm::dbgs() << " S: 0x" << Twine::utohexstr(S); - llvm::dbgs() << " A: 0x" << Twine::utohexstr(A); - llvm::dbgs() << " P: 0x" << Twine::utohexstr(P); - llvm::dbgs() << " result: 0x" << Twine::utohexstr(result) << "\n"); - write64le(location, result | read64le(location)); -} - -/// \brief R_AARCH64_ABS32 - word32: S + A -static std::error_code relocR_AARCH64_ABS32(uint8_t *location, uint64_t P, - uint64_t S, int64_t A) { - int64_t result = S + A; - if (!withinSignedUnsignedRange(result, 32)) - return make_out_of_range_reloc_error(); - DEBUG(llvm::dbgs() << "\t\tHandle " << LLVM_FUNCTION_NAME << " -"; - llvm::dbgs() << " S: 0x" << Twine::utohexstr(S); - llvm::dbgs() << " A: 0x" << Twine::utohexstr(A); - llvm::dbgs() << " P: 0x" << Twine::utohexstr(P); - llvm::dbgs() << " result: 0x" << Twine::utohexstr(result) << "\n"); - write32le(location, result | read32le(location)); - return std::error_code(); -} - -/// \brief R_AARCH64_ABS16 - word16: S + A -static std::error_code relocR_AARCH64_ABS16(uint8_t *location, uint64_t P, - uint64_t S, int64_t A) { - int64_t result = S + A; - if (!withinSignedUnsignedRange(result, 16)) - return make_out_of_range_reloc_error(); - DEBUG(llvm::dbgs() << "\t\tHandle " << LLVM_FUNCTION_NAME << " -"; - llvm::dbgs() << " S: 0x" << Twine::utohexstr(S); - llvm::dbgs() << " A: 0x" << Twine::utohexstr(A); - llvm::dbgs() << " P: 0x" << Twine::utohexstr(P); - llvm::dbgs() << " result: 0x" << Twine::utohexstr(result) << "\n"); - write16le(location, result | read16le(location)); - return std::error_code(); -} - -/// \brief R_AARCH64_PREL64 - word64: S + A - P -static void relocR_AARCH64_PREL64(uint8_t *location, uint64_t P, - uint64_t S, int64_t A) { - int64_t result = S + A - P; - DEBUG(llvm::dbgs() << "\t\tHandle " << LLVM_FUNCTION_NAME << " -"; - llvm::dbgs() << " S: 0x" << Twine::utohexstr(S); - llvm::dbgs() << " A: 0x" << Twine::utohexstr(A); - llvm::dbgs() << " P: 0x" << Twine::utohexstr(P); - llvm::dbgs() << " result: 0x" << Twine::utohexstr(result) << "\n"); - write64le(location, result + read64le(location)); -} - -/// \brief R_AARCH64_PREL32 - word32: S + A - P -static std::error_code relocR_AARCH64_PREL32(uint8_t *location, uint64_t P, - uint64_t S, int64_t A) { - int64_t result = S + A - P; - // ELF for the ARM 64-bit architecture manual states the overflow - // for R_AARCH64_PREL32 to be -2^(-31) <= X < 2^32 - if (!withinSignedUnsignedRange(result, 32)) - return make_out_of_range_reloc_error(); - DEBUG(llvm::dbgs() << "\t\tHandle " << LLVM_FUNCTION_NAME << " -"; - llvm::dbgs() << " S: 0x" << Twine::utohexstr(S); - llvm::dbgs() << " A: 0x" << Twine::utohexstr(A); - llvm::dbgs() << " P: 0x" << Twine::utohexstr(P); - llvm::dbgs() << " result: 0x" << Twine::utohexstr(result) << "\n"); - write32le(location, result + read32le(location)); - return std::error_code(); -} - -/// \brief R_AARCH64_PREL16 - word16: S + A - P -static std::error_code relocR_AARCH64_PREL16(uint8_t *location, uint64_t P, - uint64_t S, int64_t A) { - int64_t result = S + A - P; - if (!withinSignedUnsignedRange(result, 16)) - return make_out_of_range_reloc_error(); - DEBUG(llvm::dbgs() << "\t\tHandle " << LLVM_FUNCTION_NAME << " -"; - llvm::dbgs() << " S: 0x" << Twine::utohexstr(S); - llvm::dbgs() << " A: 0x" << Twine::utohexstr(A); - llvm::dbgs() << " P: 0x" << Twine::utohexstr(P); - llvm::dbgs() << " result: 0x" << Twine::utohexstr(result) << "\n"); - write16le(location, result + read16le(location)); - return std::error_code(); -} - -/// \brief R_AARCH64_ADR_PREL_PG_HI21 - Page(S+A) - Page(P) -static std::error_code relocR_AARCH64_ADR_PREL_PG_HI21(uint8_t *location, - uint64_t P, uint64_t S, - int64_t A) { - int64_t result = page(S + A) - page(P); - if (!isInt<32>(result)) - return make_out_of_range_reloc_error(); - result = result >> 12; - uint32_t immlo = result & 0x3; - uint32_t immhi = result & 0x1FFFFC; - immlo = immlo << 29; - immhi = immhi << 3; - DEBUG(llvm::dbgs() << "\t\tHandle " << LLVM_FUNCTION_NAME << " -"; - llvm::dbgs() << " S: " << Twine::utohexstr(S); - llvm::dbgs() << " A: " << Twine::utohexstr(A); - llvm::dbgs() << " P: " << Twine::utohexstr(P); - llvm::dbgs() << " immhi: " << Twine::utohexstr(immhi); - llvm::dbgs() << " immlo: " << Twine::utohexstr(immlo); - llvm::dbgs() << " result: " << Twine::utohexstr(result) << "\n"); - write32le(location, immlo | immhi | read32le(location)); - return std::error_code(); -} - -/// \brief R_AARCH64_ADR_PREL_LO21 - S + A - P -static std::error_code relocR_AARCH64_ADR_PREL_LO21(uint8_t *location, uint64_t P, - uint64_t S, int64_t A) { - uint64_t result = S + A - P; - if (!isInt<20>(result)) - return make_out_of_range_reloc_error(); - uint32_t immlo = result & 0x3; - uint32_t immhi = result & 0x1FFFFC; - immlo = immlo << 29; - immhi = immhi << 3; - DEBUG(llvm::dbgs() << "\t\tHandle " << LLVM_FUNCTION_NAME << " -"; - llvm::dbgs() << " S: " << Twine::utohexstr(S); - llvm::dbgs() << " A: " << Twine::utohexstr(A); - llvm::dbgs() << " P: " << Twine::utohexstr(P); - llvm::dbgs() << " immhi: " << Twine::utohexstr(immhi); - llvm::dbgs() << " immlo: " << Twine::utohexstr(immlo); - llvm::dbgs() << " result: " << Twine::utohexstr(result) << "\n"); - write32le(location, immlo | immhi | read32le(location)); - return std::error_code(); -} - -/// \brief R_AARCH64_ADD_ABS_LO12_NC -static void relocR_AARCH64_ADD_ABS_LO12_NC(uint8_t *location, uint64_t P, - uint64_t S, int64_t A) { - int32_t result = (int32_t)((S + A) & 0xFFF); - result <<= 10; - DEBUG(llvm::dbgs() << "\t\tHandle " << LLVM_FUNCTION_NAME << " -"; - llvm::dbgs() << " S: " << Twine::utohexstr(S); - llvm::dbgs() << " A: " << Twine::utohexstr(A); - llvm::dbgs() << " P: " << Twine::utohexstr(P); - llvm::dbgs() << " result: " << Twine::utohexstr(result) << "\n"); - write32le(location, result | read32le(location)); -} - -/// \brief R_AARCH64_CALL26 and R_AARCH64_JUMP26 -static std::error_code relocJump26(uint8_t *location, uint64_t P, uint64_t S, - int64_t A) { - int64_t result = S + A - P; - if (!isInt<27>(result)) - return make_out_of_range_reloc_error(); - result &= 0x0FFFFFFC; - result >>= 2; - DEBUG(llvm::dbgs() << "\t\tHandle " << LLVM_FUNCTION_NAME << " -"; - llvm::dbgs() << " S: " << Twine::utohexstr(S); - llvm::dbgs() << " A: " << Twine::utohexstr(A); - llvm::dbgs() << " P: " << Twine::utohexstr(P); - llvm::dbgs() << " result: " << Twine::utohexstr(result) << "\n"); - write32le(location, result | read32le(location)); - return std::error_code(); -} - -/// \brief R_AARCH64_CONDBR19 -static std::error_code relocR_AARCH64_CONDBR19(uint8_t *location, uint64_t P, - uint64_t S, int64_t A) { - int64_t result = S + A - P; - if (!isInt<20>(result)) - return make_out_of_range_reloc_error(); - result &= 0x01FFFFC; - result <<= 3; - DEBUG(llvm::dbgs() << "\t\tHandle " << LLVM_FUNCTION_NAME << " -"; - llvm::dbgs() << " S: " << Twine::utohexstr(S); - llvm::dbgs() << " A: " << Twine::utohexstr(A); - llvm::dbgs() << " P: " << Twine::utohexstr(P); - llvm::dbgs() << " result: " << Twine::utohexstr(result) << "\n"); - write32le(location, result | read32le(location)); - return std::error_code(); -} - -/// \brief R_AARCH64_LDST8_ABS_LO12_NC - S + A -static void relocR_AARCH64_LDST8_ABS_LO12_NC(uint8_t *location, uint64_t P, - uint64_t S, int64_t A) { - int32_t result = (int32_t)((S + A) & 0xFFF); - result <<= 10; - DEBUG(llvm::dbgs() << "\t\tHandle " << LLVM_FUNCTION_NAME << " -"; - llvm::dbgs() << " S: " << Twine::utohexstr(S); - llvm::dbgs() << " A: " << Twine::utohexstr(A); - llvm::dbgs() << " P: " << Twine::utohexstr(P); - llvm::dbgs() << " result: " << Twine::utohexstr(result) << "\n"); - write32le(location, result | read32le(location)); -} - -/// \brief R_AARCH64_LDST16_ABS_LO12_NC -static void relocR_AARCH64_LDST16_ABS_LO12_NC(uint8_t *location, uint64_t P, - uint64_t S, int64_t A) { - int32_t result = (int32_t)(S + A); - result &= 0x0FFC; - result <<= 9; - DEBUG(llvm::dbgs() << "\t\tHandle " << LLVM_FUNCTION_NAME << " -"; - llvm::dbgs() << " S: " << Twine::utohexstr(S); - llvm::dbgs() << " A: " << Twine::utohexstr(A); - llvm::dbgs() << " P: " << Twine::utohexstr(P); - llvm::dbgs() << " result: " << Twine::utohexstr(result) << "\n"); - write32le(location, result | read32le(location)); -} - -/// \brief R_AARCH64_LDST32_ABS_LO12_NC -static void relocR_AARCH64_LDST32_ABS_LO12_NC(uint8_t *location, uint64_t P, - uint64_t S, int64_t A) { - int32_t result = (int32_t)(S + A); - result &= 0x0FFC; - result <<= 8; - DEBUG(llvm::dbgs() << "\t\tHandle " << LLVM_FUNCTION_NAME << " -"; - llvm::dbgs() << " S: " << Twine::utohexstr(S); - llvm::dbgs() << " A: " << Twine::utohexstr(A); - llvm::dbgs() << " P: " << Twine::utohexstr(P); - llvm::dbgs() << " result: " << Twine::utohexstr(result) << "\n"); - write32le(location, result | read32le(location)); -} - -/// \brief R_AARCH64_LDST64_ABS_LO12_NC -static void relocR_AARCH64_LDST64_ABS_LO12_NC(uint8_t *location, uint64_t P, - uint64_t S, int64_t A) { - int32_t result = (int32_t)(S + A); - result &= 0x0FF8; - result <<= 7; - DEBUG(llvm::dbgs() << "\t\tHandle " << LLVM_FUNCTION_NAME << " -"; - llvm::dbgs() << " S: " << Twine::utohexstr(S); - llvm::dbgs() << " A: " << Twine::utohexstr(A); - llvm::dbgs() << " P: " << Twine::utohexstr(P); - llvm::dbgs() << " result: " << Twine::utohexstr(result) << "\n"); - write32le(location, result | read32le(location)); -} - -/// \brief R_AARCH64_LDST128_ABS_LO12_NC -static void relocR_AARCH64_LDST128_ABS_LO12_NC(uint8_t *location, uint64_t P, - uint64_t S, int64_t A) { - int32_t result = (int32_t)(S + A); - result &= 0x0FF8; - result <<= 6; - DEBUG(llvm::dbgs() << "\t\tHandle " << LLVM_FUNCTION_NAME << " -"; - llvm::dbgs() << " S: " << Twine::utohexstr(S); - llvm::dbgs() << " A: " << Twine::utohexstr(A); - llvm::dbgs() << " P: " << Twine::utohexstr(P); - llvm::dbgs() << " result: " << Twine::utohexstr(result) << "\n"); - write32le(location, result | read32le(location)); -} - -static std::error_code relocR_AARCH64_ADR_GOT_PAGE(uint8_t *location, - uint64_t P, uint64_t S, - int64_t A) { - uint64_t result = page(S + A) - page(P); - if (!isInt<32>(result)) - return make_out_of_range_reloc_error(); - result = (result >> 12) & 0x3FFFF; - uint32_t immlo = result & 0x3; - uint32_t immhi = result & 0x1FFFFC; - immlo = immlo << 29; - immhi = immhi << 3; - DEBUG(llvm::dbgs() << "\t\tHandle " << LLVM_FUNCTION_NAME << " -"; - llvm::dbgs() << " S: " << Twine::utohexstr(S); - llvm::dbgs() << " A: " << Twine::utohexstr(A); - llvm::dbgs() << " P: " << Twine::utohexstr(P); - llvm::dbgs() << " immhi: " << Twine::utohexstr(immhi); - llvm::dbgs() << " immlo: " << Twine::utohexstr(immlo); - llvm::dbgs() << " result: " << Twine::utohexstr(result) << "\n"); - write32le(location, immlo | immhi | read32le(location)); - return std::error_code(); -} - -// R_AARCH64_LD64_GOT_LO12_NC -static std::error_code relocR_AARCH64_LD64_GOT_LO12_NC(uint8_t *location, - uint64_t P, uint64_t S, - int64_t A) { - int32_t result = S + A; - DEBUG(llvm::dbgs() << " S: " << Twine::utohexstr(S); - llvm::dbgs() << " A: " << Twine::utohexstr(A); - llvm::dbgs() << " P: " << Twine::utohexstr(P); - llvm::dbgs() << " result: " << Twine::utohexstr(result) << "\n"); - if ((result & 0x7) != 0) - return make_unaligned_range_reloc_error(); - result &= 0xFF8; - result <<= 7; - write32le(location, result | read32le(location)); - return std::error_code(); -} - -// ADD_AARCH64_GOTRELINDEX -static void relocADD_AARCH64_GOTRELINDEX(uint8_t *location, uint64_t P, - uint64_t S, int64_t A) { - int32_t result = S + A; - DEBUG(llvm::dbgs() << "\t\tHandle " << LLVM_FUNCTION_NAME << " -"; - llvm::dbgs() << " S: " << Twine::utohexstr(S); - llvm::dbgs() << " A: " << Twine::utohexstr(A); - llvm::dbgs() << " P: " << Twine::utohexstr(P); - llvm::dbgs() << " result: " << Twine::utohexstr(result) << "\n"); - result &= 0xFFF; - result <<= 10; - write32le(location, result | read32le(location)); -} - -// R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21 -static std::error_code relocR_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21(uint8_t *location, - uint64_t P, - uint64_t S, - int64_t A) { - int64_t result = page(S + A) - page(P); - if (!isInt<32>(result)) - return make_out_of_range_reloc_error(); - result >>= 12; - uint32_t immlo = result & 0x3; - uint32_t immhi = result & 0x1FFFFC; - immlo = immlo << 29; - immhi = immhi << 3; - DEBUG(llvm::dbgs() << "\t\tHandle " << LLVM_FUNCTION_NAME << " -"; - llvm::dbgs() << " S: " << Twine::utohexstr(S); - llvm::dbgs() << " A: " << Twine::utohexstr(A); - llvm::dbgs() << " P: " << Twine::utohexstr(P); - llvm::dbgs() << " immhi: " << Twine::utohexstr(immhi); - llvm::dbgs() << " immlo: " << Twine::utohexstr(immlo); - llvm::dbgs() << " result: " << Twine::utohexstr(result) << "\n"); - write32le(location, immlo | immhi | read32le(location)); - return std::error_code(); -} - -// R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC -static void relocR_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC(uint8_t *location, - uint64_t P, uint64_t S, - int64_t A) { - int32_t result = S + A; - result &= 0xFF8; - result <<= 7; - DEBUG(llvm::dbgs() << "\t\tHandle " << LLVM_FUNCTION_NAME << " -"; - llvm::dbgs() << " S: " << Twine::utohexstr(S); - llvm::dbgs() << " A: " << Twine::utohexstr(A); - llvm::dbgs() << " P: " << Twine::utohexstr(P); - llvm::dbgs() << " result: " << Twine::utohexstr(result) << "\n"); - write32le(location, result | read32le(location)); -} - -/// \brief R_AARCH64_TLSLE_ADD_TPREL_HI12 -static std::error_code relocR_AARCH64_TLSLE_ADD_TPREL_HI12(uint8_t *location, - uint64_t P, - uint64_t S, - int64_t A) { - int64_t result = S + A; - if (!isUInt<24>(result)) - return make_out_of_range_reloc_error(); - result &= 0x0FFF000; - result >>= 2; - DEBUG(llvm::dbgs() << "\t\tHandle " << LLVM_FUNCTION_NAME << " -"; - llvm::dbgs() << " S: " << Twine::utohexstr(S); - llvm::dbgs() << " A: " << Twine::utohexstr(A); - llvm::dbgs() << " P: " << Twine::utohexstr(P); - llvm::dbgs() << " result: " << Twine::utohexstr(result) << "\n"); - write32le(location, result | read32le(location)); - return std::error_code(); -} - -/// \brief R_AARCH64_TLSLE_ADD_TPREL_LO12_NC -static void relocR_AARCH64_TLSLE_ADD_TPREL_LO12_NC(uint8_t *location, - uint64_t P, uint64_t S, - int64_t A) { - int32_t result = S + A; - result &= 0x0FFF; - result <<= 10; - DEBUG(llvm::dbgs() << "\t\tHandle " << LLVM_FUNCTION_NAME << " -"; - llvm::dbgs() << " S: " << Twine::utohexstr(S); - llvm::dbgs() << " A: " << Twine::utohexstr(A); - llvm::dbgs() << " P: " << Twine::utohexstr(P); - llvm::dbgs() << " result: " << Twine::utohexstr(result) << "\n"); - write32le(location, result | read32le(location)); -} - -/// \brief R_AARCH64_TLSDESC_ADR_PAGE21 - Page(G(GTLSDESC(S+A))) - Page(P) -static std::error_code relocR_AARCH64_TLSDESC_ADR_PAGE21(uint8_t *location, - uint64_t P, uint64_t S, - int64_t A) { - int64_t result = page(S + A) - page(P); - if (!isInt<32>(result)) - return make_out_of_range_reloc_error(); - result = result >> 12; - uint32_t immlo = result & 0x3; - uint32_t immhi = result & 0x1FFFFC; - immlo = immlo << 29; - immhi = immhi << 3; - DEBUG(llvm::dbgs() << "\t\tHandle " << LLVM_FUNCTION_NAME << " -"; - llvm::dbgs() << " S: " << Twine::utohexstr(S); - llvm::dbgs() << " A: " << Twine::utohexstr(A); - llvm::dbgs() << " P: " << Twine::utohexstr(P); - llvm::dbgs() << " immhi: " << Twine::utohexstr(immhi); - llvm::dbgs() << " immlo: " << Twine::utohexstr(immlo); - llvm::dbgs() << " result: " << Twine::utohexstr(result) << "\n"); - write32le(location, immlo | immhi | read32le(location)); - return std::error_code(); -} - -/// \brief R_AARCH64_TLSDESC_LD64_LO12_NC - G(GTLSDESC(S+A)) -> S + A -static std::error_code relocR_AARCH64_TLSDESC_LD64_LO12_NC(uint8_t *location, - uint64_t P, - uint64_t S, - int64_t A) { - int32_t result = S + A; - DEBUG(llvm::dbgs() << " S: " << Twine::utohexstr(S); - llvm::dbgs() << " A: " << Twine::utohexstr(A); - llvm::dbgs() << " P: " << Twine::utohexstr(P); - llvm::dbgs() << " result: " << Twine::utohexstr(result) << "\n"); - if ((result & 0x7) != 0) - return make_unaligned_range_reloc_error(); - result &= 0xFF8; - result <<= 7; - write32le(location, result | read32le(location)); - return std::error_code(); -} - -/// \brief R_AARCH64_TLSDESC_ADD_LO12_NC - G(GTLSDESC(S+A)) -> S + A -static void relocR_AARCH64_TLSDESC_ADD_LO12_NC(uint8_t *location, uint64_t P, - uint64_t S, int64_t A) { - int32_t result = (int32_t)((S + A) & 0xFFF); - result <<= 10; - DEBUG(llvm::dbgs() << "\t\tHandle " << LLVM_FUNCTION_NAME << " -"; - llvm::dbgs() << " S: " << Twine::utohexstr(S); - llvm::dbgs() << " A: " << Twine::utohexstr(A); - llvm::dbgs() << " P: " << Twine::utohexstr(P); - llvm::dbgs() << " result: " << Twine::utohexstr(result) << "\n"); - write32le(location, result | read32le(location)); -} - -std::error_code AArch64TargetRelocationHandler::applyRelocation( - ELFWriter &writer, llvm::FileOutputBuffer &buf, const AtomLayout &atom, - const Reference &ref) const { - uint8_t *atomContent = buf.getBufferStart() + atom._fileOffset; - uint8_t *loc = atomContent + ref.offsetInAtom(); - uint64_t target = writer.addressOfAtom(ref.target()); - uint64_t reloc = atom._virtualAddr + ref.offsetInAtom(); - int64_t addend = ref.addend(); - - if (ref.kindNamespace() != Reference::KindNamespace::ELF) - return std::error_code(); - assert(ref.kindArch() == Reference::KindArch::AArch64); - switch (ref.kindValue()) { - case R_AARCH64_NONE: - break; - case R_AARCH64_ABS64: - relocR_AARCH64_ABS64(loc, reloc, target, addend); - break; - case R_AARCH64_ABS32: - return relocR_AARCH64_ABS32(loc, reloc, target, addend); - case R_AARCH64_ABS16: - return relocR_AARCH64_ABS16(loc, reloc, target, addend); - case R_AARCH64_PREL64: - relocR_AARCH64_PREL64(loc, reloc, target, addend); - break; - case R_AARCH64_PREL32: - return relocR_AARCH64_PREL32(loc, reloc, target, addend); - case R_AARCH64_PREL16: - return relocR_AARCH64_PREL16(loc, reloc, target, addend); - case R_AARCH64_ADR_PREL_PG_HI21: - return relocR_AARCH64_ADR_PREL_PG_HI21(loc, reloc, target, addend); - case R_AARCH64_ADR_PREL_LO21: - return relocR_AARCH64_ADR_PREL_LO21(loc, reloc, target, addend); - case R_AARCH64_ADD_ABS_LO12_NC: - relocR_AARCH64_ADD_ABS_LO12_NC(loc, reloc, target, addend); - break; - case R_AARCH64_CALL26: - case R_AARCH64_JUMP26: - return relocJump26(loc, reloc, target, addend); - case R_AARCH64_CONDBR19: - return relocR_AARCH64_CONDBR19(loc, reloc, target, addend); - case R_AARCH64_ADR_GOT_PAGE: - return relocR_AARCH64_ADR_GOT_PAGE(loc, reloc, target, addend); - case R_AARCH64_LD64_GOT_LO12_NC: - return relocR_AARCH64_LD64_GOT_LO12_NC(loc, reloc, target, addend); - case R_AARCH64_LDST8_ABS_LO12_NC: - relocR_AARCH64_LDST8_ABS_LO12_NC(loc, reloc, target, addend); - break; - case R_AARCH64_LDST16_ABS_LO12_NC: - relocR_AARCH64_LDST16_ABS_LO12_NC(loc, reloc, target, addend); - break; - case R_AARCH64_LDST32_ABS_LO12_NC: - relocR_AARCH64_LDST32_ABS_LO12_NC(loc, reloc, target, addend); - break; - case R_AARCH64_LDST64_ABS_LO12_NC: - relocR_AARCH64_LDST64_ABS_LO12_NC(loc, reloc, target, addend); - break; - case R_AARCH64_LDST128_ABS_LO12_NC: - relocR_AARCH64_LDST128_ABS_LO12_NC(loc, reloc, target, addend); - break; - case ADD_AARCH64_GOTRELINDEX: - relocADD_AARCH64_GOTRELINDEX(loc, reloc, target, addend); - break; - case R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21: - return relocR_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21(loc, reloc, target, addend); - case R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC: - relocR_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC(loc, reloc, target, addend); - break; - case R_AARCH64_TLSLE_ADD_TPREL_HI12: - case R_AARCH64_TLSLE_ADD_TPREL_LO12_NC: { - auto tpoffset = _layout.getTPOffset(); - if (ref.kindValue() == R_AARCH64_TLSLE_ADD_TPREL_HI12) - return relocR_AARCH64_TLSLE_ADD_TPREL_HI12(loc, reloc, target + tpoffset, - addend); - else - relocR_AARCH64_TLSLE_ADD_TPREL_LO12_NC(loc, reloc, target + tpoffset, - addend); - } break; - case R_AARCH64_TLSDESC_ADR_PAGE21: - return relocR_AARCH64_TLSDESC_ADR_PAGE21(loc, reloc, target, addend); - case R_AARCH64_TLSDESC_LD64_LO12_NC: - return relocR_AARCH64_TLSDESC_LD64_LO12_NC(loc, reloc, target, addend); - case R_AARCH64_TLSDESC_ADD_LO12_NC: - relocR_AARCH64_TLSDESC_ADD_LO12_NC(loc, reloc, target, addend); - break; - case R_AARCH64_TLSDESC_CALL: - // Relaxation only to optimize TLS access. Ignore for now. - break; - // Runtime only relocations. Ignore here. - case R_AARCH64_RELATIVE: - case R_AARCH64_IRELATIVE: - case R_AARCH64_JUMP_SLOT: - case R_AARCH64_GLOB_DAT: - case R_AARCH64_TLS_TPREL64: - case R_AARCH64_TLSDESC: - break; - default: - return make_unhandled_reloc_error(); - } - return std::error_code(); -} diff --git a/lib/ReaderWriter/ELF/AArch64/AArch64RelocationHandler.h b/lib/ReaderWriter/ELF/AArch64/AArch64RelocationHandler.h deleted file mode 100644 index 8cde7a03e51a..000000000000 --- a/lib/ReaderWriter/ELF/AArch64/AArch64RelocationHandler.h +++ /dev/null @@ -1,36 +0,0 @@ -//===- lib/ReaderWriter/ELF/AArch64/AArch64RelocationHandler.h ------------===// -// -// The LLVM Linker -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef AARCH64_RELOCATION_HANDLER_H -#define AARCH64_RELOCATION_HANDLER_H - -#include "lld/ReaderWriter/ELFLinkingContext.h" - -namespace lld { -namespace elf { - -class AArch64TargetLayout; - -class AArch64TargetRelocationHandler final : public TargetRelocationHandler { -public: - AArch64TargetRelocationHandler(AArch64TargetLayout &layout) - : _layout(layout) {} - - std::error_code applyRelocation(ELFWriter &, llvm::FileOutputBuffer &, - const AtomLayout &, - const Reference &) const override; - -private: - AArch64TargetLayout &_layout; -}; - -} // end namespace elf -} // end namespace lld - -#endif // AArch64_RELOCATION_HANDLER_H diff --git a/lib/ReaderWriter/ELF/AArch64/AArch64RelocationPass.cpp b/lib/ReaderWriter/ELF/AArch64/AArch64RelocationPass.cpp deleted file mode 100644 index 4d94a793665c..000000000000 --- a/lib/ReaderWriter/ELF/AArch64/AArch64RelocationPass.cpp +++ /dev/null @@ -1,612 +0,0 @@ -//===- lib/ReaderWriter/ELF/AArch64/AArch64RelocationPass.cpp -------------===// -// -// The LLVM Linker -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -/// -/// \file -/// \brief Defines the relocation processing pass for AArch64. This includes -/// GOT and PLT entries, TLS, COPY, and ifunc. -/// -/// This also includes additional behavior that gnu-ld and gold implement but -/// which is not specified anywhere. -/// -//===----------------------------------------------------------------------===// - -#include "AArch64RelocationPass.h" -#include "AArch64LinkingContext.h" -#include "Atoms.h" -#include "lld/Core/Simple.h" -#include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/STLExtras.h" -#include "llvm/Support/Debug.h" - -using namespace lld; -using namespace lld::elf; -using namespace llvm::ELF; - -// .got values -static const uint8_t AArch64GotAtomContent[8] = {0}; - -// tls descriptor .got values, the layout is: -// struct tlsdesc { -// ptrdiff_t (*entry) (struct tlsdesc *); -// void *arg; -// }; -static const uint8_t AArch64TlsdescGotAtomContent[16] = {0}; - -// .plt value (entry 0) -static const uint8_t AArch64Plt0AtomContent[32] = { - 0xf0, 0x7b, 0xbf, 0xa9, // stp x16, x30, [sp,#-16]! - 0x10, 0x00, 0x00, 0x90, // adrp x16, Page(eh_frame) - 0x11, 0x02, 0x40, 0xf9, // ldr x17, [x16,#offset] - 0x10, 0x02, 0x00, 0x91, // add x16, x16, #offset - 0x20, 0x02, 0x1f, 0xd6, // br x17 - 0x1f, 0x20, 0x03, 0xd5, // nop - 0x1f, 0x20, 0x03, 0xd5, // nop - 0x1f, 0x20, 0x03, 0xd5 // nop -}; - -// .plt values (other entries) -static const uint8_t AArch64PltAtomContent[16] = { - 0x10, 0x00, 0x00, 0x90, // adrp x16, PAGE(<GLOBAL_OFFSET_TABLE>) - 0x11, 0x02, 0x40, 0xf9, // ldr x17, [x16,#offset] - 0x10, 0x02, 0x00, 0x91, // add x16, x16, #offset - 0x20, 0x02, 0x1f, 0xd6 // br x17 -}; - -// .plt tlsdesc values -static const uint8_t AArch64PltTlsdescAtomContent[32] = { - 0xe2, 0x0f, 0xbf, 0xa9, // stp x2, x3, [sp, #-16] - 0x02, 0x00, 0x00, 0x90, // adpr x2, 0 - 0x03, 0x00, 0x00, 0x90, // adpr x3, 0 - 0x42, 0x00, 0x40, 0xf9, // ldr x2, [x2, #0] - 0x63, 0x00, 0x00, 0x91, // add x3, x3, 0 - 0x40, 0x00, 0x1f, 0xd6, // br x2 - 0x1f, 0x20, 0x03, 0xd5, // nop - 0x1f, 0x20, 0x03, 0xd5 // nop -}; - -namespace { - -/// \brief Atoms that are used by AArch64 dynamic linking -class AArch64GOTAtom : public GOTAtom { -public: - AArch64GOTAtom(const File &f) : GOTAtom(f, ".got") {} - - ArrayRef<uint8_t> rawContent() const override { - return ArrayRef<uint8_t>(AArch64GotAtomContent, 8); - } - -protected: - // Constructor for AArch64GOTAtom - AArch64GOTAtom(const File &f, StringRef secName) : GOTAtom(f, secName) {} -}; - -class AArch64GOTPLTAtom : public AArch64GOTAtom { -public: - AArch64GOTPLTAtom(const File &f) : AArch64GOTAtom(f, ".got.plt") {} -}; - -class AArch64TLSDESCGOTAtom : public AArch64GOTPLTAtom { -public: - AArch64TLSDESCGOTAtom(const File &f) : AArch64GOTPLTAtom(f) {} - - ArrayRef<uint8_t> rawContent() const override { - return ArrayRef<uint8_t>(AArch64TlsdescGotAtomContent, 16); - } -}; - - -class AArch64PLT0Atom : public PLT0Atom { -public: - AArch64PLT0Atom(const File &f) : PLT0Atom(f) {} - ArrayRef<uint8_t> rawContent() const override { - return ArrayRef<uint8_t>(AArch64Plt0AtomContent, 32); - } -}; - -class AArch64PLTAtom : public PLTAtom { -public: - AArch64PLTAtom(const File &f) : PLTAtom(f, ".plt") {} - - ArrayRef<uint8_t> rawContent() const override { - return ArrayRef<uint8_t>(AArch64PltAtomContent, 16); - } -}; - -class AArch64PLTTLSDESCAtom : public PLTAtom { -public: - AArch64PLTTLSDESCAtom(const File &f) : PLTAtom(f, ".plt") {} - - ArrayRef<uint8_t> rawContent() const override { - return ArrayRef<uint8_t>(AArch64PltTlsdescAtomContent, 32); - } -}; - -class ELFPassFile : public SimpleFile { -public: - ELFPassFile(const ELFLinkingContext &eti) : SimpleFile("ELFPassFile") { - setOrdinal(eti.getNextOrdinalAndIncrement()); - } - - llvm::BumpPtrAllocator _alloc; -}; - -/// \brief CRTP base for handling relocations. -template <class Derived> class AArch64RelocationPass : public Pass { - /// \brief Handle a specific reference. - void handleReference(const DefinedAtom &atom, const Reference &ref) { - DEBUG_WITH_TYPE( - "AArch64", llvm::dbgs() - << "\t" << LLVM_FUNCTION_NAME << "()" - << ": Name of Defined Atom: " << atom.name().str(); - llvm::dbgs() << " kindValue: " << ref.kindValue() << "\n"); - if (ref.kindNamespace() != Reference::KindNamespace::ELF) - return; - assert(ref.kindArch() == Reference::KindArch::AArch64); - switch (ref.kindValue()) { - case R_AARCH64_ABS32: - case R_AARCH64_ABS16: - case R_AARCH64_ABS64: - case R_AARCH64_PREL16: - case R_AARCH64_PREL32: - case R_AARCH64_PREL64: - static_cast<Derived *>(this)->handlePlain(ref); - break; - case R_AARCH64_GOTREL32: - case R_AARCH64_GOTREL64: - static_cast<Derived *>(this)->handleGOT(ref); - break; - case R_AARCH64_ADR_PREL_PG_HI21: - static_cast<Derived *>(this)->handlePlain(ref); - break; - case R_AARCH64_LDST8_ABS_LO12_NC: - case R_AARCH64_LDST16_ABS_LO12_NC: - case R_AARCH64_LDST32_ABS_LO12_NC: - case R_AARCH64_LDST64_ABS_LO12_NC: - case R_AARCH64_LDST128_ABS_LO12_NC: - static_cast<Derived *>(this)->handlePlain(ref); - break; - case R_AARCH64_ADD_ABS_LO12_NC: - static_cast<Derived *>(this)->handlePlain(ref); - break; - case R_AARCH64_CALL26: - case R_AARCH64_JUMP26: - case R_AARCH64_CONDBR19: - static_cast<Derived *>(this)->handlePlain(ref); - break; - case R_AARCH64_TLSLE_ADD_TPREL_HI12: - case R_AARCH64_TLSLE_ADD_TPREL_LO12_NC: - static_cast<Derived *>(this)->handlePlain(ref); - break; - case R_AARCH64_ADR_GOT_PAGE: - case R_AARCH64_LD64_GOT_LO12_NC: - static_cast<Derived *>(this)->handleGOT(ref); - break; - case R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21: - case R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC: - static_cast<Derived *>(this)->handleGOTTPREL(ref); - break; - case R_AARCH64_TLSDESC_ADR_PAGE21: - case R_AARCH64_TLSDESC_LD64_LO12_NC: - case R_AARCH64_TLSDESC_ADD_LO12_NC: - static_cast<Derived *>(this)->handleTLSDESC(ref); - break; - } - } - -protected: - /// \brief get the PLT entry for a given IFUNC Atom. - /// - /// If the entry does not exist. Both the GOT and PLT entry is created. - const PLTAtom *getIFUNCPLTEntry(const DefinedAtom *da) { - auto plt = _pltMap.find(da); - if (plt != _pltMap.end()) - return plt->second; - auto ga = new (_file._alloc) AArch64GOTPLTAtom(_file); - ga->addReferenceELF_AArch64(R_AARCH64_IRELATIVE, 0, da, 0); - auto pa = new (_file._alloc) AArch64PLTAtom(_file); - pa->addReferenceELF_AArch64(R_AARCH64_PREL32, 2, ga, -4); -#ifndef NDEBUG - ga->_name = "__got_ifunc_"; - ga->_name += da->name(); - pa->_name = "__plt_ifunc_"; - pa->_name += da->name(); -#endif - _gotMap[da] = ga; - _pltMap[da] = pa; - _gotVector.push_back(ga); - _pltVector.push_back(pa); - return pa; - } - - /// \brief Redirect the call to the PLT stub for the target IFUNC. - /// - /// This create a PLT and GOT entry for the IFUNC if one does not exist. The - /// GOT entry and a IRELATIVE relocation to the original target resolver. - std::error_code handleIFUNC(const Reference &ref) { - auto target = dyn_cast_or_null<const DefinedAtom>(ref.target()); - if (target && target->contentType() == DefinedAtom::typeResolver) - const_cast<Reference &>(ref).setTarget(getIFUNCPLTEntry(target)); - return std::error_code(); - } - - /// \brief Create a GOT entry for the TP offset of a TLS atom. - const GOTAtom *getGOTTPREL(const Atom *atom) { - auto got = _gotMap.find(atom); - if (got == _gotMap.end()) { - auto g = new (_file._alloc) AArch64GOTAtom(_file); - g->addReferenceELF_AArch64(R_AARCH64_TLS_TPREL64, 0, atom, 0); -#ifndef NDEBUG - g->_name = "__got_tls_"; - g->_name += atom->name(); -#endif - _gotMap[atom] = g; - _gotVector.push_back(g); - return g; - } - return got->second; - } - - /// \brief Create a GOT TPREL entry to local or external TLS variable. - std::error_code handleGOTTPREL(const Reference &ref) { - if (isa<DefinedAtom>(ref.target()) || - isa<SharedLibraryAtom>(ref.target())) - const_cast<Reference &>(ref).setTarget(getGOTTPREL(ref.target())); - return std::error_code(); - } - - /// \brief Generates a double GOT entry with R_AARCH64_TLSDESC dynamic - /// relocation reference. Since the dynamic relocation is resolved - /// lazily so the GOT associated should be in .got.plt. - const GOTAtom *getTLSDESCPLTEntry(const Atom *da) { - auto got = _gotMap.find(da); - if (got != _gotMap.end()) - return got->second; - auto ga = new (_file._alloc) AArch64TLSDESCGOTAtom(_file); - ga->addReferenceELF_AArch64(R_AARCH64_TLSDESC, 0, da, 0); - auto pa = new (_file._alloc) AArch64PLTTLSDESCAtom(_file); - pa->addReferenceELF_AArch64(R_AARCH64_ADR_PREL_PG_HI21, 4, ga, 0); - pa->addReferenceELF_AArch64(R_AARCH64_ADR_PREL_PG_HI21, 8, ga, 0); - pa->addReferenceELF_AArch64(R_AARCH64_LDST64_ABS_LO12_NC, 12, ga, 0); - pa->addReferenceELF_AArch64(R_AARCH64_ADD_ABS_LO12_NC, 16, ga, 0); -#ifndef NDEBUG - ga->_name = "__got_tlsdesc_"; - ga->_name += da->name(); - pa->_name = "__plt_tlsdesc_"; - pa->_name += da->name(); -#endif - _gotMap[da] = ga; - _pltMap[da] = pa; - _tlsdescVector.push_back(ga); - _pltVector.push_back(pa); - return ga; - } - - std::error_code handleTLSDESC(const Reference &ref) { - if (isa<DefinedAtom>(ref.target()) || - isa<SharedLibraryAtom>(ref.target())) { - const_cast<Reference &>(ref).setTarget(getTLSDESCPLTEntry(ref.target())); - } - return std::error_code(); - } - - /// \brief Create a GOT entry containing 0. - const GOTAtom *getNullGOT() { - if (!_null) { - _null = new (_file._alloc) AArch64GOTPLTAtom(_file); -#ifndef NDEBUG - _null->_name = "__got_null"; -#endif - } - return _null; - } - - const GOTAtom *getGOT(const DefinedAtom *da) { - auto got = _gotMap.find(da); - if (got == _gotMap.end()) { - auto g = new (_file._alloc) AArch64GOTAtom(_file); - g->addReferenceELF_AArch64(R_AARCH64_ABS64, 0, da, 0); -#ifndef NDEBUG - g->_name = "__got_"; - g->_name += da->name(); -#endif - _gotMap[da] = g; - _gotVector.push_back(g); - return g; - } - return got->second; - } - -public: - AArch64RelocationPass(const ELFLinkingContext &ctx) : _file(ctx), _ctx(ctx) {} - - /// \brief Do the pass. - /// - /// The goal here is to first process each reference individually. Each call - /// to handleReference may modify the reference itself and/or create new - /// atoms which must be stored in one of the maps below. - /// - /// After all references are handled, the atoms created during that are all - /// added to mf. - std::error_code perform(SimpleFile &mf) override { - ScopedTask task(getDefaultDomain(), "AArch64 GOT/PLT Pass"); - DEBUG_WITH_TYPE( - "AArch64", llvm::dbgs() << "Undefined Atoms" - << "\n"; - for (const auto &atom - : mf.undefined()) { - llvm::dbgs() << " Name of Atom: " << atom->name().str() << "\n"; - } llvm::dbgs() - << "Shared Library Atoms" - << "\n"; - for (const auto &atom - : mf.sharedLibrary()) { - llvm::dbgs() << " Name of Atom: " << atom->name().str() << "\n"; - } llvm::dbgs() - << "Absolute Atoms" - << "\n"; - for (const auto &atom - : mf.absolute()) { - llvm::dbgs() << " Name of Atom: " << atom->name().str() << "\n"; - } - // Process all references. - llvm::dbgs() - << "Defined Atoms" - << "\n"); - for (const auto &atom : mf.defined()) { - for (const auto &ref : *atom) { - handleReference(*atom, *ref); - } - } - - // Add all created atoms to the link. - uint64_t ordinal = 0; - if (_plt0) { - _plt0->setOrdinal(ordinal++); - mf.addAtom(*_plt0); - } - for (auto &plt : _pltVector) { - plt->setOrdinal(ordinal++); - mf.addAtom(*plt); - } - if (_null) { - _null->setOrdinal(ordinal++); - mf.addAtom(*_null); - } - if (_plt0) { - _got0->setOrdinal(ordinal++); - _got1->setOrdinal(ordinal++); - mf.addAtom(*_got0); - mf.addAtom(*_got1); - } - for (auto &got : _gotVector) { - got->setOrdinal(ordinal++); - mf.addAtom(*got); - } - // Add any tlsdesc GOT relocation after default PLT and iFUNC entries. - for (auto &tlsdesc : _tlsdescVector) { - tlsdesc->setOrdinal(ordinal++); - mf.addAtom(*tlsdesc); - } - for (auto obj : _objectVector) { - obj->setOrdinal(ordinal++); - mf.addAtom(*obj); - } - - return std::error_code(); - } - -protected: - /// \brief Owner of all the Atoms created by this pass. - ELFPassFile _file; - const ELFLinkingContext &_ctx; - - /// \brief Map Atoms to their GOT entries. - llvm::DenseMap<const Atom *, GOTAtom *> _gotMap; - - /// \brief Map Atoms to their PLT entries. - llvm::DenseMap<const Atom *, PLTAtom *> _pltMap; - - /// \brief Map Atoms to their Object entries. - llvm::DenseMap<const Atom *, ObjectAtom *> _objectMap; - - /// \brief the list of GOT/PLT atoms - std::vector<GOTAtom *> _gotVector; - std::vector<GOTAtom *> _tlsdescVector; - std::vector<PLTAtom *> _pltVector; - std::vector<ObjectAtom *> _objectVector; - - /// \brief GOT entry that is always 0. Used for undefined weaks. - GOTAtom *_null = nullptr; - - /// \brief The got and plt entries for .PLT0. This is used to call into the - /// dynamic linker for symbol resolution. - /// @{ - PLT0Atom *_plt0 = nullptr; - GOTAtom *_got0 = nullptr; - GOTAtom *_got1 = nullptr; - /// @} -}; - -/// This implements the static relocation model. Meaning GOT and PLT entries are -/// not created for references that can be directly resolved. These are -/// converted to a direct relocation. For entries that do require a GOT or PLT -/// entry, that entry is statically bound. -/// -/// TLS always assumes module 1 and attempts to remove indirection. -class AArch64StaticRelocationPass final - : public AArch64RelocationPass<AArch64StaticRelocationPass> { -public: - AArch64StaticRelocationPass(const elf::AArch64LinkingContext &ctx) - : AArch64RelocationPass(ctx) {} - - std::error_code handlePlain(const Reference &ref) { return handleIFUNC(ref); } - - std::error_code handlePLT32(const Reference &ref) { - // __tls_get_addr is handled elsewhere. - if (ref.target() && ref.target()->name() == "__tls_get_addr") { - const_cast<Reference &>(ref).setKindValue(R_AARCH64_NONE); - return std::error_code(); - } - // Static code doesn't need PLTs. - const_cast<Reference &>(ref).setKindValue(R_AARCH64_PREL32); - // Handle IFUNC. - if (const DefinedAtom *da = - dyn_cast_or_null<const DefinedAtom>(ref.target())) - if (da->contentType() == DefinedAtom::typeResolver) - return handleIFUNC(ref); - return std::error_code(); - } - - std::error_code handleGOT(const Reference &ref) { - if (isa<UndefinedAtom>(ref.target())) - const_cast<Reference &>(ref).setTarget(getNullGOT()); - else if (const DefinedAtom *da = dyn_cast<const DefinedAtom>(ref.target())) - const_cast<Reference &>(ref).setTarget(getGOT(da)); - return std::error_code(); - } -}; - -class AArch64DynamicRelocationPass final - : public AArch64RelocationPass<AArch64DynamicRelocationPass> { -public: - AArch64DynamicRelocationPass(const elf::AArch64LinkingContext &ctx) - : AArch64RelocationPass(ctx) {} - - const PLT0Atom *getPLT0() { - if (_plt0) - return _plt0; - // Fill in the null entry. - getNullGOT(); - _plt0 = new (_file._alloc) AArch64PLT0Atom(_file); - _got0 = new (_file._alloc) AArch64GOTPLTAtom(_file); - _got1 = new (_file._alloc) AArch64GOTPLTAtom(_file); - _plt0->addReferenceELF_AArch64(R_AARCH64_ADR_GOT_PAGE, 4, _got0, 0); - _plt0->addReferenceELF_AArch64(R_AARCH64_LD64_GOT_LO12_NC, 8, _got1, 0); - _plt0->addReferenceELF_AArch64(ADD_AARCH64_GOTRELINDEX, 12, _got1, 0); -#ifndef NDEBUG - _plt0->_name = "__PLT0"; - _got0->_name = "__got0"; - _got1->_name = "__got1"; -#endif - return _plt0; - } - - const PLTAtom *getPLTEntry(const Atom *a) { - auto plt = _pltMap.find(a); - if (plt != _pltMap.end()) - return plt->second; - auto ga = new (_file._alloc) AArch64GOTPLTAtom(_file); - ga->addReferenceELF_AArch64(R_AARCH64_JUMP_SLOT, 0, a, 0); - auto pa = new (_file._alloc) AArch64PLTAtom(_file); - pa->addReferenceELF_AArch64(R_AARCH64_ADR_GOT_PAGE, 0, ga, 0); - pa->addReferenceELF_AArch64(R_AARCH64_LD64_GOT_LO12_NC, 4, ga, 0); - pa->addReferenceELF_AArch64(ADD_AARCH64_GOTRELINDEX, 8, ga, 0); - pa->addReferenceELF_AArch64(R_AARCH64_NONE, 12, getPLT0(), 0); - // Set the starting address of the got entry to the first instruction in - // the plt0 entry. - ga->addReferenceELF_AArch64(R_AARCH64_ABS32, 0, getPLT0(), 0); -#ifndef NDEBUG - ga->_name = "__got_"; - ga->_name += a->name(); - pa->_name = "__plt_"; - pa->_name += a->name(); -#endif - _gotMap[a] = ga; - _pltMap[a] = pa; - _gotVector.push_back(ga); - _pltVector.push_back(pa); - return pa; - } - - const ObjectAtom *getObjectEntry(const SharedLibraryAtom *a) { - auto obj = _objectMap.find(a); - if (obj != _objectMap.end()) - return obj->second; - - auto oa = new (_file._alloc) ObjectAtom(_file); - // This needs to point to the atom that we just created. - oa->addReferenceELF_AArch64(R_AARCH64_COPY, 0, oa, 0); - - oa->_name = a->name(); - oa->_size = a->size(); - - _objectMap[a] = oa; - _objectVector.push_back(oa); - return oa; - } - - std::error_code handlePlain(const Reference &ref) { - if (!ref.target()) - return std::error_code(); - if (auto sla = dyn_cast<SharedLibraryAtom>(ref.target())) { - if (sla->type() == SharedLibraryAtom::Type::Data) - const_cast<Reference &>(ref).setTarget(getObjectEntry(sla)); - else if (sla->type() == SharedLibraryAtom::Type::Code) - const_cast<Reference &>(ref).setTarget(getPLTEntry(sla)); - } else - return handleIFUNC(ref); - return std::error_code(); - } - - std::error_code handlePLT32(const Reference &ref) { - // Turn this into a PC32 to the PLT entry. - const_cast<Reference &>(ref).setKindValue(R_AARCH64_PREL32); - // Handle IFUNC. - if (const DefinedAtom *da = - dyn_cast_or_null<const DefinedAtom>(ref.target())) - if (da->contentType() == DefinedAtom::typeResolver) - return handleIFUNC(ref); - if (isa<const SharedLibraryAtom>(ref.target())) - const_cast<Reference &>(ref).setTarget(getPLTEntry(ref.target())); - return std::error_code(); - } - - const GOTAtom *getSharedGOT(const SharedLibraryAtom *sla) { - auto got = _gotMap.find(sla); - if (got == _gotMap.end()) { - auto g = new (_file._alloc) AArch64GOTAtom(_file); - g->addReferenceELF_AArch64(R_AARCH64_GLOB_DAT, 0, sla, 0); -#ifndef NDEBUG - g->_name = "__got_"; - g->_name += sla->name(); -#endif - _gotMap[sla] = g; - _gotVector.push_back(g); - return g; - } - return got->second; - } - - std::error_code handleGOT(const Reference &ref) { - if (isa<UndefinedAtom>(ref.target())) - const_cast<Reference &>(ref).setTarget(getNullGOT()); - else if (const DefinedAtom *da = dyn_cast<const DefinedAtom>(ref.target())) - const_cast<Reference &>(ref).setTarget(getGOT(da)); - else if (const auto sla = dyn_cast<const SharedLibraryAtom>(ref.target())) - const_cast<Reference &>(ref).setTarget(getSharedGOT(sla)); - return std::error_code(); - } -}; -} // end anon namespace - -std::unique_ptr<Pass> -lld::elf::createAArch64RelocationPass(const AArch64LinkingContext &ctx) { - switch (ctx.getOutputELFType()) { - case llvm::ELF::ET_EXEC: - if (ctx.isDynamic()) - return llvm::make_unique<AArch64DynamicRelocationPass>(ctx); - return llvm::make_unique<AArch64StaticRelocationPass>(ctx); - case llvm::ELF::ET_DYN: - return llvm::make_unique<AArch64DynamicRelocationPass>(ctx); - case llvm::ELF::ET_REL: - return nullptr; - default: - llvm_unreachable("Unhandled output file type"); - } -} diff --git a/lib/ReaderWriter/ELF/AArch64/AArch64RelocationPass.h b/lib/ReaderWriter/ELF/AArch64/AArch64RelocationPass.h deleted file mode 100644 index 73d784e3b52d..000000000000 --- a/lib/ReaderWriter/ELF/AArch64/AArch64RelocationPass.h +++ /dev/null @@ -1,32 +0,0 @@ -//===- lib/ReaderWriter/ELF/AArch64/AArch64RelocationPass.h ---------------===// -// -// The LLVM Linker -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -/// -/// \file -/// \brief Declares the relocation processing pass for AArch64. This includes -/// GOT and PLT entries, TLS, COPY, and ifunc. -/// -//===----------------------------------------------------------------------===// - -#ifndef LLD_READER_WRITER_ELF_AARCH64_AARCH64_RELOCATION_PASS_H -#define LLD_READER_WRITER_ELF_AARCH64_AARCH64_RELOCATION_PASS_H - -#include <memory> - -namespace lld { -class Pass; -namespace elf { -class AArch64LinkingContext; - -/// \brief Create AArch64 relocation pass for the given linking context. -std::unique_ptr<Pass> -createAArch64RelocationPass(const AArch64LinkingContext &); -} -} - -#endif diff --git a/lib/ReaderWriter/ELF/AArch64/AArch64SectionChunks.cpp b/lib/ReaderWriter/ELF/AArch64/AArch64SectionChunks.cpp deleted file mode 100644 index 2734bcdbda5f..000000000000 --- a/lib/ReaderWriter/ELF/AArch64/AArch64SectionChunks.cpp +++ /dev/null @@ -1,39 +0,0 @@ -//===- lib/ReaderWriter/ELF/AArch64/AArch64SectionChunks.cpp --------------===// -// -// The LLVM Linker -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "AArch64SectionChunks.h" -#include "TargetLayout.h" - -namespace lld { -namespace elf { - -AArch64GOTSection::AArch64GOTSection(const ELFLinkingContext &ctx, - StringRef name, int32_t order) - : AtomSection<ELF64LE>(ctx, name, DefinedAtom::typeGOT, DefinedAtom::permRW_, - order) { - _alignment = 8; -} - -const AtomLayout *AArch64GOTSection::appendAtom(const Atom *atom) { - const DefinedAtom *da = dyn_cast<DefinedAtom>(atom); - - for (const auto &r : *da) { - if (r->kindNamespace() != Reference::KindNamespace::ELF) - continue; - assert(r->kindArch() == Reference::KindArch::AArch64); - if ((r->kindValue() == R_AARCH64_TLS_TPREL64) || - (r->kindValue() == R_AARCH64_TLSDESC)) - _tlsMap[r->target()] = _tlsMap.size(); - } - - return AtomSection<ELF64LE>::appendAtom(atom); -} - -} // elf -} // lld diff --git a/lib/ReaderWriter/ELF/AArch64/AArch64SectionChunks.h b/lib/ReaderWriter/ELF/AArch64/AArch64SectionChunks.h deleted file mode 100644 index 2b7594c2db84..000000000000 --- a/lib/ReaderWriter/ELF/AArch64/AArch64SectionChunks.h +++ /dev/null @@ -1,37 +0,0 @@ -//===- lib/ReaderWriter/ELF/AArch64/AArch64SectionChunks.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_SECTION_CHUNKS_H -#define LLD_READER_WRITER_ELF_AARCH64_AARCH64_SECTION_CHUNKS_H - -#include "TargetLayout.h" - -namespace lld { -namespace elf { - -class AArch64GOTSection : public AtomSection<ELF64LE> { -public: - AArch64GOTSection(const ELFLinkingContext &ctx, StringRef name, - int32_t order); - - bool hasGlobalGOTEntry(const Atom *a) const { - return _tlsMap.count(a); - } - - const AtomLayout *appendAtom(const Atom *atom) override; - -private: - /// \brief Map TLS Atoms to their GOT entry index. - llvm::DenseMap<const Atom *, std::size_t> _tlsMap; -}; - -} // elf -} // lld - -#endif diff --git a/lib/ReaderWriter/ELF/AArch64/AArch64TargetHandler.cpp b/lib/ReaderWriter/ELF/AArch64/AArch64TargetHandler.cpp deleted file mode 100644 index 083b492c1607..000000000000 --- a/lib/ReaderWriter/ELF/AArch64/AArch64TargetHandler.cpp +++ /dev/null @@ -1,51 +0,0 @@ -//===- lib/ReaderWriter/ELF/AArch64/AArch64TargetHandler.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 "AArch64DynamicLibraryWriter.h" -#include "AArch64ExecutableWriter.h" -#include "AArch64LinkingContext.h" -#include "AArch64TargetHandler.h" -#include "AArch64SectionChunks.h" - -using namespace lld; -using namespace elf; - -AArch64TargetLayout::AArch64TargetLayout(ELFLinkingContext &ctx) : - TargetLayout(ctx) {} - -AtomSection<ELF64LE> *AArch64TargetLayout::createSection( - StringRef name, int32_t type, DefinedAtom::ContentPermissions permissions, - TargetLayout<ELF64LE>::SectionOrder order) { - if (type == DefinedAtom::typeGOT && (name == ".got" || name == ".got.plt")) { - auto section = new (this->_allocator) AArch64GOTSection(this->_ctx, name, - order); - _gotSections.push_back(section); - return section; - } - return TargetLayout<ELF64LE>::createSection(name, type, permissions, order); -} - - -AArch64TargetHandler::AArch64TargetHandler(AArch64LinkingContext &ctx) - : _ctx(ctx), _targetLayout(new AArch64TargetLayout(ctx)), - _relocationHandler(new AArch64TargetRelocationHandler(*_targetLayout)) {} - -std::unique_ptr<Writer> AArch64TargetHandler::getWriter() { - switch (this->_ctx.getOutputELFType()) { - case llvm::ELF::ET_EXEC: - return llvm::make_unique<AArch64ExecutableWriter>(_ctx, *_targetLayout); - case llvm::ELF::ET_DYN: - return llvm::make_unique<AArch64DynamicLibraryWriter>(_ctx, *_targetLayout); - case llvm::ELF::ET_REL: - llvm_unreachable("TODO: support -r mode"); - default: - llvm_unreachable("unsupported output type"); - } -} diff --git a/lib/ReaderWriter/ELF/AArch64/AArch64TargetHandler.h b/lib/ReaderWriter/ELF/AArch64/AArch64TargetHandler.h deleted file mode 100644 index c0ecbfa9e44b..000000000000 --- a/lib/ReaderWriter/ELF/AArch64/AArch64TargetHandler.h +++ /dev/null @@ -1,90 +0,0 @@ -//===- lib/ReaderWriter/ELF/AArch64/AArch64TargetHandler.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_TARGET_HANDLER_H -#define LLD_READER_WRITER_ELF_AARCH64_AARCH64_TARGET_HANDLER_H - -#include "AArch64RelocationHandler.h" -#include "ELFReader.h" -#include "TargetLayout.h" -#include "lld/Core/Simple.h" - -namespace lld { -namespace elf { - -class AArch64LinkingContext; -class AArch64GOTSection; - -class AArch64TargetLayout final : public TargetLayout<ELF64LE> { - typedef llvm::object::Elf_Shdr_Impl<ELF64LE> Elf_Shdr; - -public: - AArch64TargetLayout(ELFLinkingContext &ctx); - - AtomSection<ELF64LE> * - createSection(StringRef name, int32_t type, - DefinedAtom::ContentPermissions permissions, - TargetLayout<ELF64LE>::SectionOrder order) override; - - const std::vector<AArch64GOTSection *> &getGOTSections() const { - return _gotSections; - } - - uint64_t getTPOffset() { - std::call_once(_tpOffOnce, [this]() { - for (const auto &phdr : *_programHeader) { - if (phdr->p_type == llvm::ELF::PT_TLS) { - _tpOff = llvm::RoundUpToAlignment(TCB_SIZE, phdr->p_align); - break; - } - } - assert(_tpOff != 0 && "TLS segment not found"); - }); - return _tpOff; - } - -private: - enum { - TCB_SIZE = 16, - }; - -private: - std::vector<AArch64GOTSection *> _gotSections; - uint64_t _tpOff = 0; - std::once_flag _tpOffOnce; -}; - -class AArch64TargetHandler final : public TargetHandler { -public: - AArch64TargetHandler(AArch64LinkingContext &ctx); - - const TargetRelocationHandler &getRelocationHandler() const override { - return *_relocationHandler; - } - - std::unique_ptr<Reader> getObjReader() override { - return llvm::make_unique<ELFReader<ELFFile<ELF64LE>>>(_ctx); - } - - std::unique_ptr<Reader> getDSOReader() override { - return llvm::make_unique<ELFReader<DynamicFile<ELF64LE>>>(_ctx); - } - - std::unique_ptr<Writer> getWriter() override; - -private: - AArch64LinkingContext &_ctx; - std::unique_ptr<AArch64TargetLayout> _targetLayout; - std::unique_ptr<AArch64TargetRelocationHandler> _relocationHandler; -}; - -} // end namespace elf -} // end namespace lld - -#endif diff --git a/lib/ReaderWriter/ELF/AArch64/CMakeLists.txt b/lib/ReaderWriter/ELF/AArch64/CMakeLists.txt deleted file mode 100644 index aae6420008a4..000000000000 --- a/lib/ReaderWriter/ELF/AArch64/CMakeLists.txt +++ /dev/null @@ -1,14 +0,0 @@ -add_lld_library(lldAArch64ELFTarget - AArch64LinkingContext.cpp - AArch64TargetHandler.cpp - AArch64RelocationHandler.cpp - AArch64RelocationPass.cpp - AArch64ExecutableWriter.cpp - AArch64SectionChunks.cpp - LINK_LIBS - lldELF - lldReaderWriter - lldCore - LLVMObject - LLVMSupport - ) diff --git a/lib/ReaderWriter/ELF/AArch64/TODO.rst b/lib/ReaderWriter/ELF/AArch64/TODO.rst deleted file mode 100644 index aa6f616ff33f..000000000000 --- a/lib/ReaderWriter/ELF/AArch64/TODO.rst +++ /dev/null @@ -1,15 +0,0 @@ -ELF AArch64 -~~~~~~~~~~~ - -Unimplemented Features -###################### - -* Just about everything! - -Unimplemented Relocations -######################### - -All of these relocations are defined in: -http://infocenter.arm.com/help/topic/com.arm.doc.ihi0056b/IHI0056B_aaelf64.pdf - - |
