aboutsummaryrefslogtreecommitdiff
path: root/lib/ReaderWriter/ELF/X86_64
diff options
context:
space:
mode:
Diffstat (limited to 'lib/ReaderWriter/ELF/X86_64')
-rw-r--r--lib/ReaderWriter/ELF/X86_64/CMakeLists.txt1
-rw-r--r--lib/ReaderWriter/ELF/X86_64/ExampleSubTarget/ExampleLinkingContext.cpp4
-rw-r--r--lib/ReaderWriter/ELF/X86_64/ExampleSubTarget/ExampleTargetHandler.cpp5
-rw-r--r--lib/ReaderWriter/ELF/X86_64/ExampleSubTarget/ExampleTargetHandler.h2
-rw-r--r--lib/ReaderWriter/ELF/X86_64/ExampleSubTarget/Makefile15
-rw-r--r--lib/ReaderWriter/ELF/X86_64/Makefile19
-rw-r--r--lib/ReaderWriter/ELF/X86_64/X86_64DynamicLibraryWriter.h38
-rw-r--r--lib/ReaderWriter/ELF/X86_64/X86_64ELFFile.h41
-rw-r--r--lib/ReaderWriter/ELF/X86_64/X86_64ELFReader.h62
-rw-r--r--lib/ReaderWriter/ELF/X86_64/X86_64ElfType.h21
-rw-r--r--lib/ReaderWriter/ELF/X86_64/X86_64ExecutableWriter.h54
-rw-r--r--lib/ReaderWriter/ELF/X86_64/X86_64LinkingContext.cpp22
-rw-r--r--lib/ReaderWriter/ELF/X86_64/X86_64LinkingContext.h7
-rw-r--r--lib/ReaderWriter/ELF/X86_64/X86_64RelocationHandler.cpp54
-rw-r--r--lib/ReaderWriter/ELF/X86_64/X86_64RelocationHandler.h10
-rw-r--r--lib/ReaderWriter/ELF/X86_64/X86_64RelocationPass.cpp62
-rw-r--r--lib/ReaderWriter/ELF/X86_64/X86_64SectionChunks.cpp37
-rw-r--r--lib/ReaderWriter/ELF/X86_64/X86_64SectionChunks.h36
-rw-r--r--lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.cpp30
-rw-r--r--lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.h83
20 files changed, 261 insertions, 342 deletions
diff --git a/lib/ReaderWriter/ELF/X86_64/CMakeLists.txt b/lib/ReaderWriter/ELF/X86_64/CMakeLists.txt
index a85d2b504630..36ea839aa674 100644
--- a/lib/ReaderWriter/ELF/X86_64/CMakeLists.txt
+++ b/lib/ReaderWriter/ELF/X86_64/CMakeLists.txt
@@ -3,6 +3,7 @@ add_llvm_library(lldX86_64ELFTarget
X86_64TargetHandler.cpp
X86_64RelocationHandler.cpp
X86_64RelocationPass.cpp
+ X86_64SectionChunks.cpp
LINK_LIBS
lldELF
lldReaderWriter
diff --git a/lib/ReaderWriter/ELF/X86_64/ExampleSubTarget/ExampleLinkingContext.cpp b/lib/ReaderWriter/ELF/X86_64/ExampleSubTarget/ExampleLinkingContext.cpp
index dbbb3ad3bc90..cb3e819aff6b 100644
--- a/lib/ReaderWriter/ELF/X86_64/ExampleSubTarget/ExampleLinkingContext.cpp
+++ b/lib/ReaderWriter/ELF/X86_64/ExampleSubTarget/ExampleLinkingContext.cpp
@@ -14,14 +14,14 @@ using namespace lld;
using namespace elf;
std::unique_ptr<ELFLinkingContext>
-ExampleLinkingContext::create(llvm::Triple triple) {
+elf::createExampleLinkingContext(llvm::Triple triple) {
if (triple.getVendorName() == "example")
return llvm::make_unique<ExampleLinkingContext>(triple);
return nullptr;
}
ExampleLinkingContext::ExampleLinkingContext(llvm::Triple triple)
- : X86_64LinkingContext(triple, std::unique_ptr<TargetHandlerBase>(
+ : X86_64LinkingContext(triple, std::unique_ptr<TargetHandler>(
new ExampleTargetHandler(*this))) {
_outputELFType = llvm::ELF::ET_LOPROC;
}
diff --git a/lib/ReaderWriter/ELF/X86_64/ExampleSubTarget/ExampleTargetHandler.cpp b/lib/ReaderWriter/ELF/X86_64/ExampleSubTarget/ExampleTargetHandler.cpp
index b66b0d903f6a..89ec6671f3a0 100644
--- a/lib/ReaderWriter/ELF/X86_64/ExampleSubTarget/ExampleTargetHandler.cpp
+++ b/lib/ReaderWriter/ELF/X86_64/ExampleSubTarget/ExampleTargetHandler.cpp
@@ -15,9 +15,8 @@ using namespace lld;
using namespace elf;
ExampleTargetHandler::ExampleTargetHandler(ExampleLinkingContext &c)
- : X86_64TargetHandler(c), _exampleContext(c) {}
+ : X86_64TargetHandler(c), _ctx(c) {}
std::unique_ptr<Writer> ExampleTargetHandler::getWriter() {
- return std::unique_ptr<Writer>(
- new X86_64ExecutableWriter(_exampleContext, *_x86_64TargetLayout));
+ return llvm::make_unique<X86_64ExecutableWriter>(_ctx, *_targetLayout);
}
diff --git a/lib/ReaderWriter/ELF/X86_64/ExampleSubTarget/ExampleTargetHandler.h b/lib/ReaderWriter/ELF/X86_64/ExampleSubTarget/ExampleTargetHandler.h
index 19a642113359..46eade5864f9 100644
--- a/lib/ReaderWriter/ELF/X86_64/ExampleSubTarget/ExampleTargetHandler.h
+++ b/lib/ReaderWriter/ELF/X86_64/ExampleSubTarget/ExampleTargetHandler.h
@@ -23,7 +23,7 @@ public:
std::unique_ptr<Writer> getWriter() override;
private:
- ExampleLinkingContext &_exampleContext;
+ ExampleLinkingContext &_ctx;
};
} // end namespace elf
} // end namespace lld
diff --git a/lib/ReaderWriter/ELF/X86_64/ExampleSubTarget/Makefile b/lib/ReaderWriter/ELF/X86_64/ExampleSubTarget/Makefile
deleted file mode 100644
index 8f0b0fead1f6..000000000000
--- a/lib/ReaderWriter/ELF/X86_64/ExampleSubTarget/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
-##===- lld/lib/ReaderWriter/ELF/X86_64/Makefile ----------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LLD_LEVEL := ../../../../..
-LIBRARYNAME := lldExampleSubTarget
-USEDLIBS = lldX86_64ELFTarget.a
-CPP.Flags += -I$(PROJ_SRC_DIR)/$(LLD_LEVEL)/lib/ReaderWriter/ELF
-
-include $(LLD_LEVEL)/Makefile
diff --git a/lib/ReaderWriter/ELF/X86_64/Makefile b/lib/ReaderWriter/ELF/X86_64/Makefile
deleted file mode 100644
index dbeb4d227050..000000000000
--- a/lib/ReaderWriter/ELF/X86_64/Makefile
+++ /dev/null
@@ -1,19 +0,0 @@
-##===- lld/lib/ReaderWriter/ELF/X86_64/Makefile ----------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LLD_LEVEL := ../../../..
-LIBRARYNAME := lldX86_64ELFTarget
-USEDLIBS = lldCore.a
-
-CPP.Flags += -I$(PROJ_SRC_DIR)/$(LLD_LEVEL)/lib/ReaderWriter/ELF
-CPP.Flags += -I$(PROJ_SRC_DIR)/$(LLD_LEVEL)/lib/ReaderWriter/ELF/X86_64/
-
-PARALLEL_DIRS := ExampleSubTarget
-
-include $(LLD_LEVEL)/Makefile
diff --git a/lib/ReaderWriter/ELF/X86_64/X86_64DynamicLibraryWriter.h b/lib/ReaderWriter/ELF/X86_64/X86_64DynamicLibraryWriter.h
index b996186115b6..f84f85223bfb 100644
--- a/lib/ReaderWriter/ELF/X86_64/X86_64DynamicLibraryWriter.h
+++ b/lib/ReaderWriter/ELF/X86_64/X86_64DynamicLibraryWriter.h
@@ -10,51 +10,33 @@
#define X86_64_DYNAMIC_LIBRARY_WRITER_H
#include "DynamicLibraryWriter.h"
-#include "X86_64ElfType.h"
#include "X86_64LinkingContext.h"
#include "X86_64TargetHandler.h"
namespace lld {
namespace elf {
-class X86_64DynamicLibraryWriter : public DynamicLibraryWriter<X86_64ELFType> {
+class X86_64DynamicLibraryWriter : public DynamicLibraryWriter<ELF64LE> {
public:
- X86_64DynamicLibraryWriter(X86_64LinkingContext &context,
+ X86_64DynamicLibraryWriter(X86_64LinkingContext &ctx,
X86_64TargetLayout &layout);
protected:
// Add any runtime files and their atoms to the output
- virtual bool createImplicitFiles(std::vector<std::unique_ptr<File>> &);
-
- virtual void finalizeDefaultAtomValues() {
- return DynamicLibraryWriter::finalizeDefaultAtomValues();
- }
-
- virtual void addDefaultAtoms() {
- return DynamicLibraryWriter::addDefaultAtoms();
- }
-
-private:
- class GOTFile : public SimpleFile {
- public:
- GOTFile(const ELFLinkingContext &eti) : SimpleFile("GOTFile") {}
- llvm::BumpPtrAllocator _alloc;
- };
-
- std::unique_ptr<GOTFile> _gotFile;
+ void createImplicitFiles(std::vector<std::unique_ptr<File>> &) override;
};
X86_64DynamicLibraryWriter::X86_64DynamicLibraryWriter(
- X86_64LinkingContext &context, X86_64TargetLayout &layout)
- : DynamicLibraryWriter(context, layout), _gotFile(new GOTFile(context)) {}
+ X86_64LinkingContext &ctx, X86_64TargetLayout &layout)
+ : DynamicLibraryWriter(ctx, layout) {}
-bool X86_64DynamicLibraryWriter::createImplicitFiles(
+void X86_64DynamicLibraryWriter::createImplicitFiles(
std::vector<std::unique_ptr<File>> &result) {
DynamicLibraryWriter::createImplicitFiles(result);
- _gotFile->addAtom(*new (_gotFile->_alloc) GLOBAL_OFFSET_TABLEAtom(*_gotFile));
- _gotFile->addAtom(*new (_gotFile->_alloc) DYNAMICAtom(*_gotFile));
- result.push_back(std::move(_gotFile));
- return true;
+ 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
diff --git a/lib/ReaderWriter/ELF/X86_64/X86_64ELFFile.h b/lib/ReaderWriter/ELF/X86_64/X86_64ELFFile.h
deleted file mode 100644
index d43840a63e7e..000000000000
--- a/lib/ReaderWriter/ELF/X86_64/X86_64ELFFile.h
+++ /dev/null
@@ -1,41 +0,0 @@
-//===- lib/ReaderWriter/ELF/X86_64/X86_64ELFFile.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_X86_64_ELF_FILE_H
-#define LLD_READER_WRITER_ELF_X86_64_ELF_FILE_H
-
-#include "ELFReader.h"
-
-namespace lld {
-namespace elf {
-
-class X86_64LinkingContext;
-
-template <class ELFT> class X86_64ELFFile : public ELFFile<ELFT> {
-public:
- X86_64ELFFile(std::unique_ptr<MemoryBuffer> mb, X86_64LinkingContext &ctx)
- : ELFFile<ELFT>(std::move(mb), ctx) {}
-
- static ErrorOr<std::unique_ptr<X86_64ELFFile>>
- create(std::unique_ptr<MemoryBuffer> mb, X86_64LinkingContext &ctx) {
- return std::unique_ptr<X86_64ELFFile<ELFT>>(
- new X86_64ELFFile<ELFT>(std::move(mb), ctx));
- }
-};
-
-template <class ELFT> class X86_64DynamicFile : public DynamicFile<ELFT> {
-public:
- X86_64DynamicFile(const X86_64LinkingContext &context, StringRef name)
- : DynamicFile<ELFT>(context, name) {}
-};
-
-} // elf
-} // lld
-
-#endif // LLD_READER_WRITER_ELF_X86_64_ELF_FILE_H
diff --git a/lib/ReaderWriter/ELF/X86_64/X86_64ELFReader.h b/lib/ReaderWriter/ELF/X86_64/X86_64ELFReader.h
deleted file mode 100644
index 9b1284c6dfa8..000000000000
--- a/lib/ReaderWriter/ELF/X86_64/X86_64ELFReader.h
+++ /dev/null
@@ -1,62 +0,0 @@
-//===- lib/ReaderWriter/ELF/X86_64/X86_64ELFReader.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_X86_64_X86_64_ELF_READER_H
-#define LLD_READER_WRITER_X86_64_X86_64_ELF_READER_H
-
-#include "ELFReader.h"
-#include "X86_64ELFFile.h"
-
-namespace lld {
-namespace elf {
-
-typedef llvm::object::ELFType<llvm::support::little, 2, true> X86_64ELFType;
-
-struct X86_64DynamicFileCreateELFTraits {
- typedef llvm::ErrorOr<std::unique_ptr<lld::SharedLibraryFile>> result_type;
-
- template <class ELFT>
- static result_type create(std::unique_ptr<llvm::MemoryBuffer> mb,
- X86_64LinkingContext &ctx) {
- return lld::elf::X86_64DynamicFile<ELFT>::create(std::move(mb), ctx);
- }
-};
-
-struct X86_64ELFFileCreateELFTraits {
- typedef llvm::ErrorOr<std::unique_ptr<lld::File>> result_type;
-
- template <class ELFT>
- static result_type create(std::unique_ptr<llvm::MemoryBuffer> mb,
- X86_64LinkingContext &ctx) {
- return lld::elf::X86_64ELFFile<ELFT>::create(std::move(mb), ctx);
- }
-};
-
-class X86_64ELFObjectReader
- : public ELFObjectReader<X86_64ELFType, X86_64ELFFileCreateELFTraits,
- X86_64LinkingContext> {
-public:
- X86_64ELFObjectReader(X86_64LinkingContext &ctx)
- : ELFObjectReader<X86_64ELFType, X86_64ELFFileCreateELFTraits,
- X86_64LinkingContext>(ctx, llvm::ELF::EM_X86_64) {}
-};
-
-class X86_64ELFDSOReader
- : public ELFDSOReader<X86_64ELFType, X86_64DynamicFileCreateELFTraits,
- X86_64LinkingContext> {
-public:
- X86_64ELFDSOReader(X86_64LinkingContext &ctx)
- : ELFDSOReader<X86_64ELFType, X86_64DynamicFileCreateELFTraits,
- X86_64LinkingContext>(ctx, llvm::ELF::EM_X86_64) {}
-};
-
-} // namespace elf
-} // namespace lld
-
-#endif // LLD_READER_WRITER_ELF_X86_64_X86_64_READER_H
diff --git a/lib/ReaderWriter/ELF/X86_64/X86_64ElfType.h b/lib/ReaderWriter/ELF/X86_64/X86_64ElfType.h
deleted file mode 100644
index 0b982e7754e2..000000000000
--- a/lib/ReaderWriter/ELF/X86_64/X86_64ElfType.h
+++ /dev/null
@@ -1,21 +0,0 @@
-//===- lib/ReaderWriter/ELF/X86_64/X86_64ElfType.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_X86_64_X86_64_ELF_TYPE_H
-#define LLD_READER_WRITER_ELF_X86_64_X86_64_ELF_TYPE_H
-
-#include "llvm/Object/ELF.h"
-
-namespace lld {
-namespace elf {
-typedef llvm::object::ELFType<llvm::support::little, 2, true> X86_64ELFType;
-}
-}
-
-#endif
diff --git a/lib/ReaderWriter/ELF/X86_64/X86_64ExecutableWriter.h b/lib/ReaderWriter/ELF/X86_64/X86_64ExecutableWriter.h
index f549ed6dcfcb..930a2de2a9e8 100644
--- a/lib/ReaderWriter/ELF/X86_64/X86_64ExecutableWriter.h
+++ b/lib/ReaderWriter/ELF/X86_64/X86_64ExecutableWriter.h
@@ -10,49 +10,45 @@
#define X86_64_EXECUTABLE_WRITER_H
#include "ExecutableWriter.h"
-#include "X86_64ElfType.h"
#include "X86_64LinkingContext.h"
namespace lld {
namespace elf {
-class X86_64ExecutableWriter : public ExecutableWriter<X86_64ELFType> {
+class X86_64ExecutableWriter : public ExecutableWriter<ELF64LE> {
public:
- X86_64ExecutableWriter(X86_64LinkingContext &context,
- X86_64TargetLayout &layout)
- : ExecutableWriter(context, layout), _gotFile(new GOTFile(context)),
- _context(context) {}
+ X86_64ExecutableWriter(X86_64LinkingContext &ctx, X86_64TargetLayout &layout)
+ : ExecutableWriter(ctx, layout), _targetLayout(layout) {}
protected:
// Add any runtime files and their atoms to the output
- virtual bool
- createImplicitFiles(std::vector<std::unique_ptr<File>> &result) {
+ void
+ createImplicitFiles(std::vector<std::unique_ptr<File>> &result) override {
ExecutableWriter::createImplicitFiles(result);
- _gotFile->addAtom(*new (_gotFile->_alloc)
- GLOBAL_OFFSET_TABLEAtom(*_gotFile));
- if (_context.isDynamic())
- _gotFile->addAtom(*new (_gotFile->_alloc) DYNAMICAtom(*_gotFile));
- result.push_back(std::move(_gotFile));
- return true;
+ 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));
}
- virtual void finalizeDefaultAtomValues() {
- return ExecutableWriter::finalizeDefaultAtomValues();
+ void buildDynamicSymbolTable(const File &file) override {
+ for (auto sec : this->_layout.sections()) {
+ if (auto section = dyn_cast<AtomSection<ELF64LE>>(sec)) {
+ for (const auto &atom : section->atoms()) {
+ if (_targetLayout.getGOTSection().hasGlobalGOTEntry(atom->_atom)) {
+ this->_dynamicSymbolTable->addSymbol(atom->_atom, section->ordinal(),
+ atom->_virtualAddr, atom);
+ }
+ }
+ }
+ }
+
+ ExecutableWriter<ELF64LE>::buildDynamicSymbolTable(file);
}
- virtual void addDefaultAtoms() {
- return ExecutableWriter::addDefaultAtoms();
- }
-
-private:
- class GOTFile : public SimpleFile {
- public:
- GOTFile(const ELFLinkingContext &eti) : SimpleFile("GOTFile") {}
- llvm::BumpPtrAllocator _alloc;
- };
-
- std::unique_ptr<GOTFile> _gotFile;
- X86_64LinkingContext &_context;
+ X86_64TargetLayout &_targetLayout;
};
} // namespace elf
diff --git a/lib/ReaderWriter/ELF/X86_64/X86_64LinkingContext.cpp b/lib/ReaderWriter/ELF/X86_64/X86_64LinkingContext.cpp
index 6a8ce8bd6496..0dcd6ac6fbed 100644
--- a/lib/ReaderWriter/ELF/X86_64/X86_64LinkingContext.cpp
+++ b/lib/ReaderWriter/ELF/X86_64/X86_64LinkingContext.cpp
@@ -12,10 +12,10 @@
#include "X86_64TargetHandler.h"
using namespace lld;
-using namespace elf;
+using namespace lld::elf;
X86_64LinkingContext::X86_64LinkingContext(
- llvm::Triple triple, std::unique_ptr<TargetHandlerBase> handler)
+ llvm::Triple triple, std::unique_ptr<TargetHandler> handler)
: ELFLinkingContext(triple, std::move(handler)) {}
X86_64LinkingContext::X86_64LinkingContext(llvm::Triple triple)
@@ -30,9 +30,21 @@ void X86_64LinkingContext::addPasses(PassManager &pm) {
}
std::unique_ptr<ELFLinkingContext>
-X86_64LinkingContext::create(llvm::Triple triple) {
+elf::createX86_64LinkingContext(llvm::Triple triple) {
if (triple.getArch() == llvm::Triple::x86_64)
- return std::unique_ptr<ELFLinkingContext>(
- new elf::X86_64LinkingContext(triple));
+ return llvm::make_unique<X86_64LinkingContext>(triple);
return nullptr;
}
+
+static const Registry::KindStrings kindStrings[] = {
+#define ELF_RELOC(name, value) LLD_KIND_STRING_ENTRY(name),
+#include "llvm/Support/ELFRelocs/x86_64.def"
+#undef ELF_RELOC
+ LLD_KIND_STRING_ENTRY(LLD_R_X86_64_GOTRELINDEX),
+ LLD_KIND_STRING_END
+};
+
+void X86_64LinkingContext::registerRelocationNames(Registry &registry) {
+ registry.addKindTable(Reference::KindNamespace::ELF,
+ Reference::KindArch::x86_64, kindStrings);
+}
diff --git a/lib/ReaderWriter/ELF/X86_64/X86_64LinkingContext.h b/lib/ReaderWriter/ELF/X86_64/X86_64LinkingContext.h
index 2cc799a9c810..a5a7b3d21f4e 100644
--- a/lib/ReaderWriter/ELF/X86_64/X86_64LinkingContext.h
+++ b/lib/ReaderWriter/ELF/X86_64/X86_64LinkingContext.h
@@ -26,12 +26,15 @@ enum {
class X86_64LinkingContext : public ELFLinkingContext {
protected:
- X86_64LinkingContext(llvm::Triple, std::unique_ptr<TargetHandlerBase>);
+ X86_64LinkingContext(llvm::Triple, std::unique_ptr<TargetHandler>);
+
public:
static std::unique_ptr<ELFLinkingContext> create(llvm::Triple);
+ int getMachineType() const override { return llvm::ELF::EM_X86_64; }
X86_64LinkingContext(llvm::Triple);
void addPasses(PassManager &) override;
+ void registerRelocationNames(Registry &r) override;
uint64_t getBaseAddress() const override {
if (_baseAddress == 0)
@@ -65,7 +68,7 @@ public:
return false;
}
- virtual bool isPLTRelocation(const Reference &r) const override {
+ bool isPLTRelocation(const Reference &r) const override {
if (r.kindNamespace() != Reference::KindNamespace::ELF)
return false;
assert(r.kindArch() == Reference::KindArch::x86_64);
diff --git a/lib/ReaderWriter/ELF/X86_64/X86_64RelocationHandler.cpp b/lib/ReaderWriter/ELF/X86_64/X86_64RelocationHandler.cpp
index 8fd74f43bbd2..d56983d1e382 100644
--- a/lib/ReaderWriter/ELF/X86_64/X86_64RelocationHandler.cpp
+++ b/lib/ReaderWriter/ELF/X86_64/X86_64RelocationHandler.cpp
@@ -23,7 +23,7 @@ static void reloc64(uint8_t *location, uint64_t P, uint64_t S, int64_t A) {
/// \brief R_X86_64_PC32 - word32: S + A - P
static void relocPC32(uint8_t *location, uint64_t P, uint64_t S, int64_t A) {
- uint32_t result = (uint32_t)((S + A) - P);
+ uint32_t result = (uint32_t)(S + A - P);
write32le(location, result + read32le(location));
}
@@ -50,24 +50,24 @@ static void reloc16(uint8_t *location, uint64_t P, uint64_t S, int64_t A) {
/// \brief R_X86_64_PC16 - word16: S + A - P
static void relocPC16(uint8_t *location, uint64_t P, uint64_t S, int64_t A) {
- uint16_t result = (uint16_t)((S + A) - P);
+ uint16_t result = (uint16_t)(S + A - P);
write16le(location, result | read16le(location));
// TODO: Check for overflow.
}
/// \brief R_X86_64_PC64 - word64: S + A - P
static void relocPC64(uint8_t *location, uint64_t P, uint64_t S, uint64_t A) {
- int64_t result = (uint64_t)((S + A) - P);
+ int64_t result = (uint64_t)(S + A - P);
write64le(location, result | read64le(location));
}
std::error_code X86_64TargetRelocationHandler::applyRelocation(
- ELFWriter &writer, llvm::FileOutputBuffer &buf, const lld::AtomLayout &atom,
+ ELFWriter &writer, llvm::FileOutputBuffer &buf, const AtomLayout &atom,
const Reference &ref) const {
uint8_t *atomContent = buf.getBufferStart() + atom._fileOffset;
- uint8_t *location = atomContent + ref.offsetInAtom();
- uint64_t targetVAddress = writer.addressOfAtom(ref.target());
- uint64_t relocVAddress = atom._virtualAddr + ref.offsetInAtom();
+ uint8_t *loc = atomContent + ref.offsetInAtom();
+ uint64_t target = writer.addressOfAtom(ref.target());
+ uint64_t reloc = atom._virtualAddr + ref.offsetInAtom();
if (ref.kindNamespace() != Reference::KindNamespace::ELF)
return std::error_code();
@@ -76,38 +76,34 @@ std::error_code X86_64TargetRelocationHandler::applyRelocation(
case R_X86_64_NONE:
break;
case R_X86_64_64:
- reloc64(location, relocVAddress, targetVAddress, ref.addend());
+ reloc64(loc, reloc, target, ref.addend());
break;
case R_X86_64_PC32:
case R_X86_64_GOTPCREL:
- relocPC32(location, relocVAddress, targetVAddress, ref.addend());
+ relocPC32(loc, reloc, target, ref.addend());
break;
case R_X86_64_32:
- reloc32(location, relocVAddress, targetVAddress, ref.addend());
+ reloc32(loc, reloc, target, ref.addend());
break;
case R_X86_64_32S:
- reloc32S(location, relocVAddress, targetVAddress, ref.addend());
+ reloc32S(loc, reloc, target, ref.addend());
break;
case R_X86_64_16:
- reloc16(location, relocVAddress, targetVAddress, ref.addend());
+ reloc16(loc, reloc, target, ref.addend());
break;
case R_X86_64_PC16:
- relocPC16(location, relocVAddress, targetVAddress, ref.addend());
+ relocPC16(loc, reloc, target, ref.addend());
break;
- case R_X86_64_TPOFF64:
case R_X86_64_DTPOFF32:
- case R_X86_64_TPOFF32: {
- _tlsSize = _x86_64Layout.getTLSSize();
- if (ref.kindValue() == R_X86_64_TPOFF32 ||
- ref.kindValue() == R_X86_64_DTPOFF32) {
- write32le(location, targetVAddress - _tlsSize);
- } else {
- write64le(location, targetVAddress - _tlsSize);
- }
+ case R_X86_64_TPOFF32:
+ _tlsSize = _layout.getTLSSize();
+ write32le(loc, target - _tlsSize);
+ break;
+ case R_X86_64_GOTTPOFF:
+ relocPC32(loc, reloc, target, ref.addend());
break;
- }
case R_X86_64_TLSGD: {
- relocPC32(location, relocVAddress, targetVAddress, ref.addend());
+ relocPC32(loc, reloc, target, ref.addend());
break;
}
case R_X86_64_TLSLD: {
@@ -115,21 +111,20 @@ std::error_code X86_64TargetRelocationHandler::applyRelocation(
// next relocation is a PC32 to __tls_get_addr...
static uint8_t instr[] = { 0x66, 0x66, 0x66, 0x64, 0x48, 0x8b, 0x04, 0x25,
0x00, 0x00, 0x00, 0x00 };
- std::memcpy(location - 3, instr, sizeof(instr));
+ std::memcpy(loc - 3, instr, sizeof(instr));
break;
}
case R_X86_64_PC64:
- relocPC64(location, relocVAddress, targetVAddress, ref.addend());
+ relocPC64(loc, reloc, target, ref.addend());
break;
case LLD_R_X86_64_GOTRELINDEX: {
const DefinedAtom *target = cast<const DefinedAtom>(ref.target());
for (const Reference *r : *target) {
if (r->kindValue() == R_X86_64_JUMP_SLOT) {
uint32_t index;
- if (!_x86_64Layout.getPLTRelocationTable()->getRelocationIndex(*r,
- index))
+ if (!_layout.getPLTRelocationTable()->getRelocationIndex(*r, index))
llvm_unreachable("Relocation doesn't exist");
- reloc32(location, 0, index, 0);
+ reloc32(loc, 0, index, 0);
break;
}
}
@@ -142,6 +137,7 @@ std::error_code X86_64TargetRelocationHandler::applyRelocation(
case R_X86_64_GLOB_DAT:
case R_X86_64_DTPMOD64:
case R_X86_64_DTPOFF64:
+ case R_X86_64_TPOFF64:
break;
default:
return make_unhandled_reloc_error();
diff --git a/lib/ReaderWriter/ELF/X86_64/X86_64RelocationHandler.h b/lib/ReaderWriter/ELF/X86_64/X86_64RelocationHandler.h
index 9e2c2171015d..26382804549b 100644
--- a/lib/ReaderWriter/ELF/X86_64/X86_64RelocationHandler.h
+++ b/lib/ReaderWriter/ELF/X86_64/X86_64RelocationHandler.h
@@ -10,27 +10,25 @@
#ifndef X86_64_RELOCATION_HANDLER_H
#define X86_64_RELOCATION_HANDLER_H
-#include "X86_64TargetHandler.h"
+#include "lld/ReaderWriter/ELFLinkingContext.h"
namespace lld {
namespace elf {
-typedef llvm::object::ELFType<llvm::support::little, 2, true> X86_64ELFType;
-
class X86_64TargetLayout;
class X86_64TargetRelocationHandler final : public TargetRelocationHandler {
public:
X86_64TargetRelocationHandler(X86_64TargetLayout &layout)
- : _tlsSize(0), _x86_64Layout(layout) {}
+ : _tlsSize(0), _layout(layout) {}
std::error_code applyRelocation(ELFWriter &, llvm::FileOutputBuffer &,
- const lld::AtomLayout &,
+ const AtomLayout &,
const Reference &) const override;
private:
// Cached size of the TLS segment.
mutable uint64_t _tlsSize;
- X86_64TargetLayout &_x86_64Layout;
+ X86_64TargetLayout &_layout;
};
} // end namespace elf
diff --git a/lib/ReaderWriter/ELF/X86_64/X86_64RelocationPass.cpp b/lib/ReaderWriter/ELF/X86_64/X86_64RelocationPass.cpp
index 0703927fd56c..a2f10dc08a4e 100644
--- a/lib/ReaderWriter/ELF/X86_64/X86_64RelocationPass.cpp
+++ b/lib/ReaderWriter/ELF/X86_64/X86_64RelocationPass.cpp
@@ -188,11 +188,12 @@ protected:
return got->second;
}
- /// \brief Create a TPOFF64 GOT entry and change the relocation to a PC32 to
- /// the GOT.
- void handleGOTTPOFF(const Reference &ref) {
- const_cast<Reference &>(ref).setTarget(getGOTTPOFF(ref.target()));
- const_cast<Reference &>(ref).setKindValue(R_X86_64_PC32);
+ /// \brief Create a TPOFF64 GOT entry.
+ std::error_code handleGOTTPOFF(const Reference &ref) {
+ if (isa<DefinedAtom>(ref.target())) {
+ const_cast<Reference &>(ref).setTarget(getGOTTPOFF(ref.target()));
+ }
+ return std::error_code();
}
/// \brief Create a TLS GOT entry with DTPMOD64/DTPOFF64 dynamic relocations.
@@ -243,9 +244,7 @@ protected:
}
public:
- RelocationPass(const ELFLinkingContext &ctx)
- : _file(ctx), _ctx(ctx), _null(nullptr), _PLT0(nullptr), _got0(nullptr),
- _got1(nullptr) {}
+ RelocationPass(const ELFLinkingContext &ctx) : _file(ctx), _ctx(ctx) {}
/// \brief Do the pass.
///
@@ -255,45 +254,46 @@ public:
///
/// After all references are handled, the atoms created during that are all
/// added to mf.
- void perform(std::unique_ptr<MutableFile> &mf) override {
+ std::error_code perform(SimpleFile &mf) override {
ScopedTask task(getDefaultDomain(), "X86-64 GOT/PLT Pass");
// Process all references.
- for (const auto &atom : mf->defined())
+ 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);
+ if (_plt0) {
+ _plt0->setOrdinal(ordinal++);
+ mf.addAtom(*_plt0);
}
for (auto &plt : _pltVector) {
plt->setOrdinal(ordinal++);
- mf->addAtom(*plt);
+ mf.addAtom(*plt);
}
if (_null) {
_null->setOrdinal(ordinal++);
- mf->addAtom(*_null);
+ mf.addAtom(*_null);
}
- if (_PLT0) {
+ if (_plt0) {
_got0->setOrdinal(ordinal++);
_got1->setOrdinal(ordinal++);
- mf->addAtom(*_got0);
- mf->addAtom(*_got1);
+ mf.addAtom(*_got0);
+ mf.addAtom(*_got1);
}
for (auto &got : _gotVector) {
got->setOrdinal(ordinal++);
- mf->addAtom(*got);
+ mf.addAtom(*got);
}
for (auto &got : _tlsGotVector) {
got->setOrdinal(ordinal++);
- mf->addAtom(*got);
+ mf.addAtom(*got);
}
for (auto obj : _objectVector) {
obj->setOrdinal(ordinal++);
- mf->addAtom(*obj);
+ mf.addAtom(*obj);
}
+ return std::error_code();
}
protected:
@@ -322,14 +322,14 @@ protected:
std::vector<GOTAtom *> _tlsGotVector;
/// \brief GOT entry that is always 0. Used for undefined weaks.
- GOTAtom *_null;
+ 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;
- GOTAtom *_got0;
- GOTAtom *_got1;
+ PLT0Atom *_plt0 = nullptr;
+ GOTAtom *_got0 = nullptr;
+ GOTAtom *_got1 = nullptr;
/// @}
};
@@ -379,20 +379,20 @@ public:
: RelocationPass(ctx) {}
const PLT0Atom *getPLT0() {
- if (_PLT0)
- return _PLT0;
+ if (_plt0)
+ return _plt0;
// Fill in the null entry.
getNullGOT();
- _PLT0 = new (_file._alloc) X86_64PLT0Atom(_file);
+ _plt0 = new (_file._alloc) X86_64PLT0Atom(_file);
_got0 = new (_file._alloc) X86_64GOTAtom(_file, ".got.plt");
_got1 = new (_file._alloc) X86_64GOTAtom(_file, ".got.plt");
- _PLT0->addReferenceELF_x86_64(R_X86_64_PC32, 2, _got0, -4);
- _PLT0->addReferenceELF_x86_64(R_X86_64_PC32, 8, _got1, -4);
+ _plt0->addReferenceELF_x86_64(R_X86_64_PC32, 2, _got0, -4);
+ _plt0->addReferenceELF_x86_64(R_X86_64_PC32, 8, _got1, -4);
#ifndef NDEBUG
_got0->_name = "__got0";
_got1->_name = "__got1";
#endif
- return _PLT0;
+ return _plt0;
}
const PLTAtom *getPLTEntry(const Atom *a) {
diff --git a/lib/ReaderWriter/ELF/X86_64/X86_64SectionChunks.cpp b/lib/ReaderWriter/ELF/X86_64/X86_64SectionChunks.cpp
new file mode 100644
index 000000000000..28eb3e4244b6
--- /dev/null
+++ b/lib/ReaderWriter/ELF/X86_64/X86_64SectionChunks.cpp
@@ -0,0 +1,37 @@
+//===- lib/ReaderWriter/ELF/X86_64/X86_64SectionChunks.cpp --------------===//
+//
+// The LLVM Linker
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "X86_64SectionChunks.h"
+#include "TargetLayout.h"
+
+namespace lld {
+namespace elf {
+
+X86_64GOTSection::X86_64GOTSection(const ELFLinkingContext &ctx)
+ : AtomSection<ELF64LE>(ctx, ".got", DefinedAtom::typeGOT, DefinedAtom::permRW_,
+ TargetLayout<ELF64LE>::ORDER_GOT) {
+ this->_alignment = 8;
+}
+
+const AtomLayout *X86_64GOTSection::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::x86_64);
+ if (r->kindValue() == R_X86_64_TPOFF64)
+ _tlsMap[r->target()] = _tlsMap.size();
+ }
+
+ return AtomSection<ELF64LE>::appendAtom(atom);
+}
+
+} // elf
+} // lld
diff --git a/lib/ReaderWriter/ELF/X86_64/X86_64SectionChunks.h b/lib/ReaderWriter/ELF/X86_64/X86_64SectionChunks.h
new file mode 100644
index 000000000000..5208491eee55
--- /dev/null
+++ b/lib/ReaderWriter/ELF/X86_64/X86_64SectionChunks.h
@@ -0,0 +1,36 @@
+//===- lib/ReaderWriter/ELF/X86_64/X86_64SectionChunks.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_X86_64_X86_64_SECTION_CHUNKS_H
+#define LLD_READER_WRITER_ELF_X86_64_X86_64_SECTION_CHUNKS_H
+
+#include "TargetLayout.h"
+
+namespace lld {
+namespace elf {
+
+class X86_64GOTSection : public AtomSection<ELF64LE> {
+public:
+ X86_64GOTSection(const ELFLinkingContext &ctx);
+
+ 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/X86_64/X86_64TargetHandler.cpp b/lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.cpp
index f35330eb25c0..599077ac33c5 100644
--- a/lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.cpp
+++ b/lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.cpp
@@ -16,37 +16,19 @@
using namespace lld;
using namespace elf;
-X86_64TargetHandler::X86_64TargetHandler(X86_64LinkingContext &context)
- : _context(context), _x86_64TargetLayout(new X86_64TargetLayout(context)),
- _x86_64RelocationHandler(
- new X86_64TargetRelocationHandler(*_x86_64TargetLayout.get())) {}
-
-void X86_64TargetHandler::registerRelocationNames(Registry &registry) {
- registry.addKindTable(Reference::KindNamespace::ELF,
- Reference::KindArch::x86_64, kindStrings);
-}
+X86_64TargetHandler::X86_64TargetHandler(X86_64LinkingContext &ctx)
+ : _ctx(ctx), _targetLayout(new X86_64TargetLayout(ctx)),
+ _relocationHandler(new X86_64TargetRelocationHandler(*_targetLayout)) {}
std::unique_ptr<Writer> X86_64TargetHandler::getWriter() {
- switch (this->_context.getOutputELFType()) {
+ switch (this->_ctx.getOutputELFType()) {
case llvm::ELF::ET_EXEC:
- return std::unique_ptr<Writer>(
- new X86_64ExecutableWriter(_context, *_x86_64TargetLayout.get()));
+ return llvm::make_unique<X86_64ExecutableWriter>(_ctx, *_targetLayout);
case llvm::ELF::ET_DYN:
- return std::unique_ptr<Writer>(
- new X86_64DynamicLibraryWriter(_context, *_x86_64TargetLayout.get()));
+ return llvm::make_unique<X86_64DynamicLibraryWriter>(_ctx, *_targetLayout);
case llvm::ELF::ET_REL:
llvm_unreachable("TODO: support -r mode");
default:
llvm_unreachable("unsupported output type");
}
}
-
-#define ELF_RELOC(name, value) LLD_KIND_STRING_ENTRY(name),
-
-const Registry::KindStrings X86_64TargetHandler::kindStrings[] = {
-#include "llvm/Support/ELFRelocs/x86_64.def"
- LLD_KIND_STRING_ENTRY(LLD_R_X86_64_GOTRELINDEX),
- LLD_KIND_STRING_END
-};
-
-#undef ELF_RELOC
diff --git a/lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.h b/lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.h
index 57da7bca01e6..6e3e58f8aed6 100644
--- a/lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.h
+++ b/lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.h
@@ -10,57 +10,92 @@
#ifndef LLD_READER_WRITER_ELF_X86_64_X86_64_TARGET_HANDLER_H
#define LLD_READER_WRITER_ELF_X86_64_X86_64_TARGET_HANDLER_H
-#include "DefaultTargetHandler.h"
+#include "ELFReader.h"
#include "TargetLayout.h"
-#include "X86_64ELFFile.h"
-#include "X86_64ELFReader.h"
#include "X86_64LinkingContext.h"
#include "X86_64RelocationHandler.h"
+#include "X86_64SectionChunks.h"
#include "lld/Core/Simple.h"
namespace lld {
namespace elf {
-class X86_64TargetLayout : public TargetLayout<X86_64ELFType> {
+
+
+class X86_64TargetLayout : public TargetLayout<ELF64LE> {
public:
- X86_64TargetLayout(X86_64LinkingContext &context)
- : TargetLayout(context) {}
+ X86_64TargetLayout(X86_64LinkingContext &ctx) : TargetLayout(ctx),
+ _gotSection(new (this->_allocator) X86_64GOTSection(ctx)) {}
+
+ AtomSection<ELF64LE> *
+ createSection(StringRef name, int32_t type,
+ DefinedAtom::ContentPermissions permissions,
+ TargetLayout<ELF64LE>::SectionOrder order) override {
+ if (type == DefinedAtom::typeGOT && name == ".got")
+ return _gotSection;
+ return TargetLayout<ELF64LE>::createSection(name, type, permissions, order);
+ }
void finalizeOutputSectionLayout() override {
- sortOutputSectionByPriority(".init_array", ".init_array");
- sortOutputSectionByPriority(".fini_array", ".fini_array");
+ sortOutputSectionByPriority<ELF64LE>(".init_array");
+ sortOutputSectionByPriority<ELF64LE>(".fini_array");
}
-};
-class X86_64TargetHandler
- : public DefaultTargetHandler<X86_64ELFType> {
-public:
- X86_64TargetHandler(X86_64LinkingContext &context);
+ const X86_64GOTSection &getGOTSection() const { return *_gotSection; }
- X86_64TargetLayout &getTargetLayout() override {
- return *(_x86_64TargetLayout.get());
+private:
+ uint32_t getPriority(StringRef sectionName) const {
+ StringRef priority = sectionName.drop_front().rsplit('.').second;
+ uint32_t prio;
+ if (priority.getAsInteger(10, prio))
+ return std::numeric_limits<uint32_t>::max();
+ return prio;
}
- void registerRelocationNames(Registry &registry) override;
+ template <typename T> void sortOutputSectionByPriority(StringRef prefix) {
+ OutputSection<T> *section = findOutputSection(prefix);
+ if (!section)
+ return;
+ auto sections = section->sections();
+ std::sort(sections.begin(), sections.end(),
+ [&](Chunk<T> *lhs, Chunk<T> *rhs) {
+ Section<T> *lhsSection = dyn_cast<Section<T>>(lhs);
+ Section<T> *rhsSection = dyn_cast<Section<T>>(rhs);
+ if (!lhsSection || !rhsSection)
+ return false;
+ StringRef lhsName = lhsSection->inputSectionName();
+ StringRef rhsName = rhsSection->inputSectionName();
+ if (!lhsName.startswith(prefix) || !rhsName.startswith(prefix))
+ return false;
+ return getPriority(lhsName) < getPriority(rhsName);
+ });
+ }
+
+private:
+ X86_64GOTSection *_gotSection;
+};
+
+class X86_64TargetHandler : public TargetHandler {
+public:
+ X86_64TargetHandler(X86_64LinkingContext &ctx);
- const X86_64TargetRelocationHandler &getRelocationHandler() const override {
- return *(_x86_64RelocationHandler.get());
+ const TargetRelocationHandler &getRelocationHandler() const override {
+ return *_relocationHandler;
}
std::unique_ptr<Reader> getObjReader() override {
- return std::unique_ptr<Reader>(new X86_64ELFObjectReader(_context));
+ return llvm::make_unique<ELFReader<ELFFile<ELF64LE>>>(_ctx);
}
std::unique_ptr<Reader> getDSOReader() override {
- return std::unique_ptr<Reader>(new X86_64ELFDSOReader(_context));
+ return llvm::make_unique<ELFReader<DynamicFile<ELF64LE>>>(_ctx);
}
std::unique_ptr<Writer> getWriter() override;
protected:
- static const Registry::KindStrings kindStrings[];
- X86_64LinkingContext &_context;
- std::unique_ptr<X86_64TargetLayout> _x86_64TargetLayout;
- std::unique_ptr<X86_64TargetRelocationHandler> _x86_64RelocationHandler;
+ X86_64LinkingContext &_ctx;
+ std::unique_ptr<X86_64TargetLayout> _targetLayout;
+ std::unique_ptr<X86_64TargetRelocationHandler> _relocationHandler;
};
} // end namespace elf