summaryrefslogtreecommitdiffstats
path: root/lld/lib/ReaderWriter/ELF
diff options
context:
space:
mode:
Diffstat (limited to 'lld/lib/ReaderWriter/ELF')
-rw-r--r--lld/lib/ReaderWriter/ELF/CMakeLists.txt1
-rw-r--r--lld/lib/ReaderWriter/ELF/DefaultELFLayout.h14
-rw-r--r--lld/lib/ReaderWriter/ELF/ELFSegmentChunks.h18
-rw-r--r--lld/lib/ReaderWriter/ELF/ELFTargetInfo.cpp13
-rw-r--r--lld/lib/ReaderWriter/ELF/ELFWriter.h2
-rw-r--r--lld/lib/ReaderWriter/ELF/ExecutableAtoms.h6
-rw-r--r--lld/lib/ReaderWriter/ELF/ReaderELF.cpp26
-rw-r--r--lld/lib/ReaderWriter/ELF/ReferenceKinds.cpp21
-rw-r--r--lld/lib/ReaderWriter/ELF/ReferenceKinds.h9
-rw-r--r--lld/lib/ReaderWriter/ELF/WriterELF.cpp54
-rw-r--r--lld/lib/ReaderWriter/ELF/WriterOptionsELF.cpp28
11 files changed, 85 insertions, 107 deletions
diff --git a/lld/lib/ReaderWriter/ELF/CMakeLists.txt b/lld/lib/ReaderWriter/ELF/CMakeLists.txt
index aa3e54cd1ab..b12d56450c1 100644
--- a/lld/lib/ReaderWriter/ELF/CMakeLists.txt
+++ b/lld/lib/ReaderWriter/ELF/CMakeLists.txt
@@ -5,7 +5,6 @@ add_lld_library(lldELF
ReaderELF.cpp
ReferenceKinds.cpp
WriterELF.cpp
- WriterOptionsELF.cpp
X86Reference.cpp
X86_64Reference.cpp
)
diff --git a/lld/lib/ReaderWriter/ELF/DefaultELFLayout.h b/lld/lib/ReaderWriter/ELF/DefaultELFLayout.h
index ae859d8d05f..86e61ecc020 100644
--- a/lld/lib/ReaderWriter/ELF/DefaultELFLayout.h
+++ b/lld/lib/ReaderWriter/ELF/DefaultELFLayout.h
@@ -10,6 +10,8 @@
#ifndef LLD_READER_WRITER_DEFAULT_ELF_LAYOUT_H_
#define LLD_READER_WRITER_DEFAULT_ELF_LAYOUT_H_
+#include "lld/Core/LinkerOptions.h"
+
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/Hashing.h"
@@ -150,7 +152,7 @@ public:
typedef typename std::vector<AbsoluteAtomPair>::iterator AbsoluteAtomIterT;
- DefaultELFLayout(const WriterOptionsELF &options) : _options(options) {}
+ DefaultELFLayout(const ELFTargetInfo &ti) : _targetInfo(ti) {}
/// \brief Return the section order for a input section
virtual SectionOrder getSectionOrder
@@ -250,7 +252,7 @@ private:
ELFProgramHeader<ELFT> *_programHeader;
std::vector<AbsoluteAtomPair> _absoluteAtoms;
llvm::BumpPtrAllocator _allocator;
- const WriterOptionsELF _options;
+ const ELFTargetInfo &_targetInfo;
};
template<class ELFT>
@@ -483,7 +485,7 @@ DefaultELFLayout<ELFT>::assignSectionsToSegments() {
segment = segmentInsert.first->second;
} else {
segment = new (_allocator.Allocate<Segment<ELFT>>()) Segment<ELFT>(
- segmentName, getSegmentType(section), _options);
+ segmentName, getSegmentType(section), _targetInfo);
segmentInsert.first->second = segment;
_segments.push_back(segment);
}
@@ -516,7 +518,7 @@ DefaultELFLayout<ELFT>::assignVirtualAddress() {
if (_segments.empty())
return;
- uint64_t virtualAddress = _options.baseAddress();
+ uint64_t virtualAddress = _targetInfo.getLinkerOptions()._baseAddress;
// HACK: This is a super dirty hack. The elf header and program header are
// not part of a section, but we need them to be loaded at the base address
@@ -539,7 +541,7 @@ DefaultELFLayout<ELFT>::assignVirtualAddress() {
for (auto &si : _segments) {
// Align the segment to a page boundary
fileoffset = llvm::RoundUpToAlignment(fileoffset,
- _options.pageSize());
+ _targetInfo.getPageSize());
si->assignOffsets(fileoffset);
fileoffset = si->fileOffset() + si->fileSize();
}
@@ -552,7 +554,7 @@ DefaultELFLayout<ELFT>::assignVirtualAddress() {
(*si)->assignVirtualAddress(address);
(*si)->setMemSize(address - virtualAddress);
virtualAddress = llvm::RoundUpToAlignment(address,
- _options.pageSize());
+ _targetInfo.getPageSize());
}
_programHeader->resetProgramHeaders();
}
diff --git a/lld/lib/ReaderWriter/ELF/ELFSegmentChunks.h b/lld/lib/ReaderWriter/ELF/ELFSegmentChunks.h
index 0e329b4c6fd..177313776b9 100644
--- a/lld/lib/ReaderWriter/ELF/ELFSegmentChunks.h
+++ b/lld/lib/ReaderWriter/ELF/ELFSegmentChunks.h
@@ -11,7 +11,7 @@
#define LLD_READER_WRITER_ELF_SEGMENT_CHUNKS_H_
#include "lld/Core/range.h"
-#include "lld/ReaderWriter/WriterELF.h"
+#include "lld/ReaderWriter/Writer.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/OwningPtr.h"
@@ -113,7 +113,7 @@ public:
Segment(const StringRef name,
const ELFLayout::SegmentType type,
- const WriterOptionsELF &options);
+ const ELFTargetInfo &ti);
/// append a section to a segment
void append(Section<ELFT> *section);
@@ -168,7 +168,7 @@ public:
inline ELFLayout::SegmentType segmentType() { return _segmentType; }
- inline int pageSize() const { return _options.pageSize(); }
+ inline int pageSize() const { return _targetInfo.getPageSize(); }
inline int64_t atomflags() const { return _atomflags; }
@@ -195,19 +195,19 @@ protected:
ELFLayout::SegmentType _segmentType;
int64_t _flags;
int64_t _atomflags;
- const WriterOptionsELF _options;
+ const ELFTargetInfo &_targetInfo;
llvm::BumpPtrAllocator _segmentAllocate;
};
template<class ELFT>
Segment<ELFT>::Segment(const StringRef name,
const ELFLayout::SegmentType type,
- const WriterOptionsELF &options)
+ const ELFTargetInfo &ti)
: Chunk<ELFT>(name, Chunk<ELFT>::K_ELFSegment)
, _segmentType(type)
, _flags(0)
, _atomflags(0)
- , _options(options) {
+ , _targetInfo(ti) {
this->_align2 = 0;
this->_fsize = 0;
}
@@ -268,7 +268,7 @@ Segment<ELFT>::assignOffsets(uint64_t startOffset) {
SegmentSlice<ELFT> *slice = nullptr;
// If the newOffset computed is more than a page away, lets create
// a seperate segment, so that memory is not used up while running
- if ((newOffset - curOffset) > _options.pageSize()) {
+ if ((newOffset - curOffset) > _targetInfo.getPageSize()) {
// TODO: use std::find here
for (auto s : slices()) {
if (s->startSection() == startSection) {
@@ -286,7 +286,7 @@ Segment<ELFT>::assignOffsets(uint64_t startOffset) {
slice->setSize(curSliceSize);
slice->setAlign(sliceAlign);
uint64_t newPageOffset =
- llvm::RoundUpToAlignment(curOffset, _options.pageSize());
+ llvm::RoundUpToAlignment(curOffset, _targetInfo.getPageSize());
newOffset = llvm::RoundUpToAlignment(newPageOffset, (*si)->align2());
curSliceFileOffset = newOffset;
startSectionIter = endSectionIter;
@@ -332,7 +332,7 @@ void
Segment<ELFT>::assignVirtualAddress(uint64_t &addr) {
for (auto slice : slices()) {
// Align to a page
- addr = llvm::RoundUpToAlignment(addr, _options.pageSize());
+ addr = llvm::RoundUpToAlignment(addr, _targetInfo.getPageSize());
// Align to the slice alignment
addr = llvm::RoundUpToAlignment(addr, slice->align2());
diff --git a/lld/lib/ReaderWriter/ELF/ELFTargetInfo.cpp b/lld/lib/ReaderWriter/ELF/ELFTargetInfo.cpp
index 9a086f83cef..5c4cbfceb00 100644
--- a/lld/lib/ReaderWriter/ELF/ELFTargetInfo.cpp
+++ b/lld/lib/ReaderWriter/ELF/ELFTargetInfo.cpp
@@ -23,6 +23,13 @@ uint16_t ELFTargetInfo::getOutputType() const {
return llvm::ELF::ET_REL;
case OutputKind::Shared:
return llvm::ELF::ET_DYN;
+ case OutputKind::Core:
+ return llvm::ELF::ET_CORE;
+ case OutputKind::SharedStubs:
+ case OutputKind::DebugSymbols:
+ case OutputKind::Bundle:
+ case OutputKind::Preload:
+ break;
}
llvm_unreachable("Unhandled OutputKind");
}
@@ -42,21 +49,21 @@ uint16_t ELFTargetInfo::getOutputMachine() const {
}
}
-class X86ELFTargetInfo final : public ELFTargetInfo {
+class X86ELFTargetInfo LLVM_FINAL : public ELFTargetInfo {
public:
X86ELFTargetInfo(const LinkerOptions &lo) : ELFTargetInfo(lo) {}
virtual uint64_t getPageSize() const { return 0x1000; }
};
-class HexagonELFTargetInfo final : public ELFTargetInfo {
+class HexagonELFTargetInfo LLVM_FINAL : public ELFTargetInfo {
public:
HexagonELFTargetInfo(const LinkerOptions &lo) : ELFTargetInfo(lo) {}
virtual uint64_t getPageSize() const { return 0x1000; }
};
-class PPCELFTargetInfo final : public ELFTargetInfo {
+class PPCELFTargetInfo LLVM_FINAL : public ELFTargetInfo {
public:
PPCELFTargetInfo(const LinkerOptions &lo) : ELFTargetInfo(lo) {}
diff --git a/lld/lib/ReaderWriter/ELF/ELFWriter.h b/lld/lib/ReaderWriter/ELF/ELFWriter.h
index 517d61c9569..20b83fd0713 100644
--- a/lld/lib/ReaderWriter/ELF/ELFWriter.h
+++ b/lld/lib/ReaderWriter/ELF/ELFWriter.h
@@ -12,7 +12,7 @@
#include "lld/Core/File.h"
#include "lld/Core/InputFiles.h"
-#include "lld/ReaderWriter/WriterELF.h"
+#include "lld/ReaderWriter/Writer.h"
#include "ReferenceKinds.h"
namespace lld {
diff --git a/lld/lib/ReaderWriter/ELF/ExecutableAtoms.h b/lld/lib/ReaderWriter/ELF/ExecutableAtoms.h
index 1820b2cbf35..f0531ac6d13 100644
--- a/lld/lib/ReaderWriter/ELF/ExecutableAtoms.h
+++ b/lld/lib/ReaderWriter/ELF/ExecutableAtoms.h
@@ -15,7 +15,7 @@
#include "lld/Core/UndefinedAtom.h"
#include "lld/Core/File.h"
#include "lld/Core/Reference.h"
-#include "lld/ReaderWriter/WriterELF.h"
+#include "lld/ReaderWriter/Writer.h"
#include "AtomsELF.h"
namespace lld {
@@ -30,9 +30,7 @@ template<class ELFT>
class CRuntimeFile : public File {
public:
typedef llvm::object::Elf_Sym_Impl<ELFT> Elf_Sym;
- CRuntimeFile(const WriterOptionsELF &options)
- : File("C runtime")
- { }
+ CRuntimeFile(const ELFTargetInfo &) : File("C runtime") {}
/// \brief add a global absolute atom
void addAbsoluteAtom(const StringRef symbolName) {
diff --git a/lld/lib/ReaderWriter/ELF/ReaderELF.cpp b/lld/lib/ReaderWriter/ELF/ReaderELF.cpp
index 16e53f221c6..deaf66354c4 100644
--- a/lld/lib/ReaderWriter/ELF/ReaderELF.cpp
+++ b/lld/lib/ReaderWriter/ELF/ReaderELF.cpp
@@ -13,10 +13,12 @@
///
//===----------------------------------------------------------------------===//
-#include "lld/ReaderWriter/ReaderELF.h"
-#include "lld/ReaderWriter/ReaderArchive.h"
+#include "lld/ReaderWriter/Reader.h"
+
#include "lld/Core/File.h"
#include "lld/Core/Reference.h"
+#include "lld/ReaderWriter/ELFTargetInfo.h"
+#include "lld/ReaderWriter/ReaderArchive.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallString.h"
@@ -326,12 +328,9 @@ private:
/// memory buffer for ELF class and bit width
class ReaderELF : public Reader {
public:
- ReaderELF(const ReaderOptionsELF &,
- ReaderOptionsArchive &readerOptionsArchive)
- : _readerOptionsArchive(readerOptionsArchive),
- _readerArchive(_readerOptionsArchive) {
- _readerOptionsArchive.setReader(this);
- }
+ ReaderELF(const TargetInfo & ti, std::function<ReaderFunc> read)
+ : Reader(ti),
+ _readerArchive(ti, read) {}
error_code parseFile(std::unique_ptr<MemoryBuffer> mb,
std::vector<std::unique_ptr<File>> &result) {
@@ -411,18 +410,13 @@ public:
}
private:
- ReaderOptionsArchive &_readerOptionsArchive;
ReaderArchive _readerArchive;
};
} // end anon namespace.
namespace lld {
-ReaderOptionsELF::ReaderOptionsELF() {}
-
-ReaderOptionsELF::~ReaderOptionsELF() {}
-
-Reader *createReaderELF(const ReaderOptionsELF &options,
- ReaderOptionsArchive &optionsArchive) {
- return new ReaderELF(options, optionsArchive);
+std::unique_ptr<Reader> createReaderELF(const TargetInfo & ti,
+ std::function<ReaderFunc> read) {
+ return std::unique_ptr<Reader>(new ReaderELF(ti, std::move(read)));
}
} // end namespace lld
diff --git a/lld/lib/ReaderWriter/ELF/ReferenceKinds.cpp b/lld/lib/ReaderWriter/ELF/ReferenceKinds.cpp
index 083e843237c..769895ab843 100644
--- a/lld/lib/ReaderWriter/ELF/ReferenceKinds.cpp
+++ b/lld/lib/ReaderWriter/ELF/ReferenceKinds.cpp
@@ -11,29 +11,30 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSwitch.h"
+#include "llvm/ADT/Triple.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/ELF.h"
namespace lld {
namespace elf {
-KindHandler::KindHandler() {
-}
+KindHandler::KindHandler() {}
-KindHandler::~KindHandler() {
-}
+KindHandler::~KindHandler() {}
std::unique_ptr<KindHandler>
-KindHandler::makeHandler(uint16_t arch, llvm::support::endianness endian) {
+KindHandler::makeHandler(llvm::Triple::ArchType arch, bool isLittleEndian) {
switch(arch) {
- case llvm::ELF::EM_HEXAGON:
+ case llvm::Triple::hexagon:
return std::unique_ptr<KindHandler>(new HexagonKindHandler());
- case llvm::ELF::EM_386:
+ case llvm::Triple::x86:
return std::unique_ptr<KindHandler>(new X86KindHandler());
- case llvm::ELF::EM_X86_64:
+ case llvm::Triple::x86_64:
return std::unique_ptr<KindHandler>(new X86_64KindHandler());
- case llvm::ELF::EM_PPC:
- return std::unique_ptr<KindHandler>(new PPCKindHandler(endian));
+ case llvm::Triple::ppc:
+ return std::unique_ptr<KindHandler>(
+ new PPCKindHandler(isLittleEndian ? llvm::support::little
+ : llvm::support::big));
default:
llvm_unreachable("arch not supported");
}
diff --git a/lld/lib/ReaderWriter/ELF/ReferenceKinds.h b/lld/lib/ReaderWriter/ELF/ReferenceKinds.h
index faa4299700c..45f6cae66da 100644
--- a/lld/lib/ReaderWriter/ELF/ReferenceKinds.h
+++ b/lld/lib/ReaderWriter/ELF/ReferenceKinds.h
@@ -9,9 +9,12 @@
#include "lld/Core/LLVM.h"
#include "lld/Core/Reference.h"
-#include "lld/ReaderWriter/WriterELF.h"
+#include "lld/ReaderWriter/Writer.h"
#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/Triple.h"
+#include "llvm/Support/ELF.h"
+#include "llvm/Support/Endian.h"
#include <functional>
#include <map>
@@ -32,8 +35,8 @@ class KindHandler {
public:
typedef Reference::Kind Kind;
- static std::unique_ptr<KindHandler> makeHandler(uint16_t arch,
- llvm::support::endianness endian);
+ static std::unique_ptr<KindHandler> makeHandler(llvm::Triple::ArchType arch,
+ bool isLittleEndian);
virtual ~KindHandler();
virtual Kind stringToKind(StringRef str) = 0;
virtual StringRef kindToString(Kind) = 0;
diff --git a/lld/lib/ReaderWriter/ELF/WriterELF.cpp b/lld/lib/ReaderWriter/ELF/WriterELF.cpp
index d9be025c5ca..73bb6bb6103 100644
--- a/lld/lib/ReaderWriter/ELF/WriterELF.cpp
+++ b/lld/lib/ReaderWriter/ELF/WriterELF.cpp
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+#include "lld/ReaderWriter/ELFTargetInfo.h"
+
#include "DefaultELFLayout.h"
#include "ExecutableAtoms.h"
@@ -26,7 +28,7 @@ public:
typedef Elf_Shdr_Impl<ELFT> Elf_Shdr;
typedef Elf_Sym_Impl<ELFT> Elf_Sym;
- ELFExecutableWriter(const WriterOptionsELF &options);
+ ELFExecutableWriter(const ELFTargetInfo &ti);
private:
// build the sections that need to be created
@@ -49,7 +51,7 @@ private:
void createDefaultSections();
- const WriterOptionsELF &_options;
+ const ELFTargetInfo &_targetInfo;
typedef llvm::DenseMap<const Atom*, uint64_t> AtomToAddress;
std::unique_ptr<KindHandler> _referenceKindHandler;
@@ -69,12 +71,12 @@ private:
// ELFExecutableWriter
//===----------------------------------------------------------------------===//
template<class ELFT>
-ELFExecutableWriter<ELFT>::ELFExecutableWriter(const WriterOptionsELF &options)
- : _options(options)
+ELFExecutableWriter<ELFT>::ELFExecutableWriter(const ELFTargetInfo &ti)
+ : _targetInfo(ti)
, _referenceKindHandler(KindHandler::makeHandler(
- _options.machine(), (endianness)ELFT::TargetEndianness))
- , _runtimeFile(options) {
- _layout =new DefaultELFLayout<ELFT>(options);
+ ti.getTriple().getArch(), ti.isLittleEndian()))
+ , _runtimeFile(ti) {
+ _layout = new DefaultELFLayout<ELFT>(ti);
}
template<class ELFT>
@@ -248,14 +250,14 @@ ELFExecutableWriter<ELFT>::writeFile(const lld::File &file, StringRef path) {
if (ec)
return ec;
- _elfHeader->e_ident(ELF::EI_CLASS, (_options.is64Bit() ? ELF::ELFCLASS64
- : ELF::ELFCLASS32));
- _elfHeader->e_ident(ELF::EI_DATA, _options.endianness() == llvm::support::big
- ? ELF::ELFDATA2MSB : ELF::ELFDATA2LSB);
+ _elfHeader->e_ident(ELF::EI_CLASS, _targetInfo.is64Bits() ? ELF::ELFCLASS64
+ : ELF::ELFCLASS32);
+ _elfHeader->e_ident(ELF::EI_DATA, _targetInfo.isLittleEndian()
+ ? ELF::ELFDATA2LSB : ELF::ELFDATA2MSB);
_elfHeader->e_ident(ELF::EI_VERSION, 1);
_elfHeader->e_ident(ELF::EI_OSABI, 0);
- _elfHeader->e_type(_options.type());
- _elfHeader->e_machine(_options.machine());
+ _elfHeader->e_type(_targetInfo.getOutputType());
+ _elfHeader->e_machine(_targetInfo.getOutputMachine());
_elfHeader->e_version(1);
_elfHeader->e_entry(0ULL);
_elfHeader->e_phoff(_programHeader->fileOffset());
@@ -305,24 +307,24 @@ void ELFExecutableWriter<ELFT>::createDefaultSections() {
}
} // namespace elf
-Writer *createWriterELF(const WriterOptionsELF &options) {
+std::unique_ptr<Writer> createWriterELF(const ELFTargetInfo &TI) {
using llvm::object::ELFType;
// Set the default layout to be the static executable layout
// We would set the layout to a dynamic executable layout
// if we came across any shared libraries in the process
- if (!options.is64Bit() && options.endianness() == llvm::support::little)
- return
- new elf::ELFExecutableWriter<ELFType<support::little, 4, false>>(options);
- else if (options.is64Bit() && options.endianness() == llvm::support::little)
- return
- new elf::ELFExecutableWriter<ELFType<support::little, 8, true>>(options);
- else if (!options.is64Bit() && options.endianness() == llvm::support::big)
- return
- new elf::ELFExecutableWriter<ELFType<support::big, 4, false>>(options);
- else if (options.is64Bit() && options.endianness() == llvm::support::big)
- return
- new elf::ELFExecutableWriter<ELFType<support::big, 8, true>>(options);
+ if (!TI.is64Bits() && TI.isLittleEndian())
+ return std::unique_ptr<Writer>(new
+ elf::ELFExecutableWriter<ELFType<support::little, 4, false>>(TI));
+ else if (TI.is64Bits() && TI.isLittleEndian())
+ return std::unique_ptr<Writer>(new
+ elf::ELFExecutableWriter<ELFType<support::little, 8, true>>(TI));
+ else if (!TI.is64Bits() && !TI.isLittleEndian())
+ return std::unique_ptr<Writer>(new
+ elf::ELFExecutableWriter<ELFType<support::big, 4, false>>(TI));
+ else if (TI.is64Bits() && !TI.isLittleEndian())
+ return std::unique_ptr<Writer>(new
+ elf::ELFExecutableWriter<ELFType<support::big, 8, true>>(TI));
llvm_unreachable("Invalid Options!");
}
diff --git a/lld/lib/ReaderWriter/ELF/WriterOptionsELF.cpp b/lld/lib/ReaderWriter/ELF/WriterOptionsELF.cpp
deleted file mode 100644
index 4d832aed05e..00000000000
--- a/lld/lib/ReaderWriter/ELF/WriterOptionsELF.cpp
+++ /dev/null
@@ -1,28 +0,0 @@
-//===- lib/ReaderWriter/ELF/WriterOptionsELF.cpp ----------------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "lld/ReaderWriter/WriterELF.h"
-
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/Support/Debug.h"
-#include "llvm/Support/ELF.h"
-#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/system_error.h"
-
-
-namespace lld {
-
-StringRef WriterOptionsELF::entryPoint() const {
- if (_type == llvm::ELF::ET_EXEC)
- return _entryPoint;
- return StringRef();
-}
-
-} // namespace lld
OpenPOWER on IntegriCloud