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/Atoms.h3
-rw-r--r--lld/lib/ReaderWriter/ELF/DefaultLayout.h3
-rw-r--r--lld/lib/ReaderWriter/ELF/DefaultTargetHandler.h1
-rw-r--r--lld/lib/ReaderWriter/ELF/ELFTargetInfo.cpp148
-rw-r--r--lld/lib/ReaderWriter/ELF/ExecutableAtoms.h1
-rw-r--r--lld/lib/ReaderWriter/ELF/ExecutableWriter.h2
-rw-r--r--lld/lib/ReaderWriter/ELF/File.h2
-rw-r--r--lld/lib/ReaderWriter/ELF/HeaderChunks.h7
-rw-r--r--lld/lib/ReaderWriter/ELF/Hexagon/HexagonRelocationFunctions.h3
-rw-r--r--lld/lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.cpp3
-rw-r--r--lld/lib/ReaderWriter/ELF/Hexagon/HexagonTargetInfo.cpp4
-rw-r--r--lld/lib/ReaderWriter/ELF/Hexagon/HexagonTargetInfo.h10
-rw-r--r--lld/lib/ReaderWriter/ELF/OutputELFWriter.h2
-rw-r--r--lld/lib/ReaderWriter/ELF/PPC/PPCTargetInfo.cpp36
-rw-r--r--lld/lib/ReaderWriter/ELF/PPC/PPCTargetInfo.h8
-rw-r--r--lld/lib/ReaderWriter/ELF/Reader.cpp17
-rw-r--r--lld/lib/ReaderWriter/ELF/SectionChunks.h6
-rw-r--r--lld/lib/ReaderWriter/ELF/TargetHandler.h1
-rw-r--r--lld/lib/ReaderWriter/ELF/Writer.cpp86
-rw-r--r--lld/lib/ReaderWriter/ELF/Writer.h2
-rw-r--r--lld/lib/ReaderWriter/ELF/X86/X86TargetInfo.cpp36
-rw-r--r--lld/lib/ReaderWriter/ELF/X86/X86TargetInfo.h7
-rw-r--r--lld/lib/ReaderWriter/ELF/X86_64/X86_64TargetInfo.cpp27
-rw-r--r--lld/lib/ReaderWriter/ELF/X86_64/X86_64TargetInfo.h14
24 files changed, 280 insertions, 149 deletions
diff --git a/lld/lib/ReaderWriter/ELF/Atoms.h b/lld/lib/ReaderWriter/ELF/Atoms.h
index c5f66bcdedf..28501d9b231 100644
--- a/lld/lib/ReaderWriter/ELF/Atoms.h
+++ b/lld/lib/ReaderWriter/ELF/Atoms.h
@@ -512,7 +512,8 @@ public:
const Elf_Shdr *section, llvm::ArrayRef<uint8_t> contentData,
uint64_t offset)
: _owningFile(file), _sectionName(sectionName), _section(section),
- _contentData(contentData), _offset(offset) {}
+ _contentData(contentData), _offset(offset) {
+ }
virtual const class ELFFile<ELFT> &file() const {
return _owningFile;
diff --git a/lld/lib/ReaderWriter/ELF/DefaultLayout.h b/lld/lib/ReaderWriter/ELF/DefaultLayout.h
index 73a4c163143..8c520ff4f7e 100644
--- a/lld/lib/ReaderWriter/ELF/DefaultLayout.h
+++ b/lld/lib/ReaderWriter/ELF/DefaultLayout.h
@@ -16,7 +16,6 @@
#include "SectionChunks.h"
#include "SegmentChunks.h"
-#include "lld/Core/LinkerOptions.h"
#include "lld/Core/STDExtras.h"
#include "llvm/ADT/ArrayRef.h"
@@ -28,6 +27,7 @@
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSwitch.h"
+#include "llvm/Support/Format.h"
#include <map>
#include <tuple>
@@ -667,7 +667,6 @@ DefaultLayout<ELFT>::assignVirtualAddress() {
}
firstLoadSegment->prepend(_programHeader);
firstLoadSegment->prepend(_header);
-
bool newSegmentHeaderAdded = true;
while (true) {
for (auto si : _segments) {
diff --git a/lld/lib/ReaderWriter/ELF/DefaultTargetHandler.h b/lld/lib/ReaderWriter/ELF/DefaultTargetHandler.h
index c6426724f25..c019df1baed 100644
--- a/lld/lib/ReaderWriter/ELF/DefaultTargetHandler.h
+++ b/lld/lib/ReaderWriter/ELF/DefaultTargetHandler.h
@@ -13,7 +13,6 @@
#include "DefaultLayout.h"
#include "TargetHandler.h"
-#include "lld/Core/LinkerOptions.h"
#include "lld/ReaderWriter/ELFTargetInfo.h"
#include "llvm/ADT/Triple.h"
diff --git a/lld/lib/ReaderWriter/ELF/ELFTargetInfo.cpp b/lld/lib/ReaderWriter/ELF/ELFTargetInfo.cpp
index 3395609979c..338096d3a2c 100644
--- a/lld/lib/ReaderWriter/ELF/ELFTargetInfo.cpp
+++ b/lld/lib/ReaderWriter/ELF/ELFTargetInfo.cpp
@@ -12,41 +12,38 @@
#include "TargetHandler.h"
#include "Targets.h"
-#include "lld/Core/LinkerOptions.h"
#include "lld/Passes/LayoutPass.h"
#include "lld/ReaderWriter/ReaderLinkerScript.h"
#include "llvm/ADT/Triple.h"
#include "llvm/Support/ELF.h"
#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Path.h"
namespace lld {
-ELFTargetInfo::ELFTargetInfo(const LinkerOptions &lo) : TargetInfo(lo) {}
-
-uint16_t ELFTargetInfo::getOutputType() const {
- switch (_options._outputKind) {
- case OutputKind::StaticExecutable:
- case OutputKind::DynamicExecutable:
- return llvm::ELF::ET_EXEC;
- case OutputKind::Relocatable:
- 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;
- case OutputKind::Invalid:
- llvm_unreachable("Invalid output kind!");
- }
- llvm_unreachable("Unhandled OutputKind");
+ELFTargetInfo::ELFTargetInfo(llvm::Triple triple)
+ : _outputFileType(elf::ET_EXEC)
+ , _triple(triple)
+ , _baseAddress(0)
+ , _isStaticExecutable(false)
+ , _outputYAML(false)
+ , _noInhibitExec(false)
+ , _mergeCommonStrings(false)
+ , _runLayoutPass(true) {
+}
+
+bool ELFTargetInfo::is64Bits() const {
+ return getTriple().isArch64Bit();
+}
+
+bool ELFTargetInfo::isLittleEndian() const {
+ // TODO: Do this properly. It is not defined purely by arch.
+ return true;
}
void ELFTargetInfo::addPasses(PassManager &pm) const {
- pm.add(std::unique_ptr<Pass>(new LayoutPass()));
+ if (_runLayoutPass)
+ pm.add(std::unique_ptr<Pass>(new LayoutPass()));
}
uint16_t ELFTargetInfo::getOutputMachine() const {
@@ -64,31 +61,63 @@ uint16_t ELFTargetInfo::getOutputMachine() const {
}
}
-ErrorOr<Reader &> ELFTargetInfo::getReader(const LinkerInput &input) const {
- DEBUG_WITH_TYPE("inputs", llvm::dbgs() << input.getPath() << "\n");
- auto buffer = input.getBuffer();
- if (!buffer)
- return error_code(buffer);
- auto magic = llvm::sys::fs::identify_magic(buffer->getBuffer());
- // Assume unknown file types are linker scripts.
- if (magic == llvm::sys::fs::file_magic::unknown) {
- if (!_linkerScriptReader)
- _linkerScriptReader.reset(new ReaderLinkerScript(
- *this,
- std::bind(&ELFTargetInfo::getReader, this, std::placeholders::_1)));
- return *_linkerScriptReader;
+bool ELFTargetInfo::validate(raw_ostream &diagnostics) {
+ if (_outputFileType == elf::ET_EXEC) {
+ if (_entrySymbolName.empty()) {
+ _entrySymbolName = "_start";
+ }
+ }
+
+ if (_inputFiles.empty()) {
+ diagnostics << "No input files\n";
+ return true;
+ }
+
+
+ return false;
+}
+
+
+bool ELFTargetInfo::isDynamic() const {
+ switch (_outputFileType) {
+ case llvm::ELF::ET_EXEC:
+ if (_isStaticExecutable)
+ return false;
+ else
+ return true;
+ case llvm::ELF::ET_DYN:
+ return true;
}
+ return false;
+}
- // Assume anything else is an ELF file.
+
+error_code ELFTargetInfo::parseFile(std::unique_ptr<MemoryBuffer> &mb,
+ std::vector<std::unique_ptr<File>> &result) const {
if (!_elfReader)
- _elfReader = createReaderELF(*this, std::bind(&ELFTargetInfo::getReader,
- this, std::placeholders::_1));
- return *_elfReader;
+ _elfReader = createReaderELF(*this);
+ error_code ec = _elfReader->parseFile(mb, result);
+ if (ec) {
+ // Not an ELF file, check file extension to see if it might be yaml
+ StringRef path = mb->getBufferIdentifier();
+ if ( path.endswith(".objtxt") ) {
+ if (!_yamlReader)
+ _yamlReader = createReaderYAML(*this);
+ ec = _yamlReader->parseFile(mb, result);
+ }
+ if (ec) {
+ // Not a yaml file, assume it is a linkerscript
+ if (!_linkerScriptReader)
+ _linkerScriptReader.reset(new ReaderLinkerScript(*this));
+ ec = _linkerScriptReader->parseFile(mb, result);
+ }
+ }
+ return ec;
}
-ErrorOr<Writer &> ELFTargetInfo::getWriter() const {
+Writer &ELFTargetInfo::writer() const {
if (!_writer) {
- if (_options._outputYAML)
+ if (_outputYAML)
_writer = createWriterYAML(*this);
else
_writer = createWriterELF(*this);
@@ -96,27 +125,40 @@ ErrorOr<Writer &> ELFTargetInfo::getWriter() const {
return *_writer;
}
-std::unique_ptr<ELFTargetInfo> ELFTargetInfo::create(const LinkerOptions &lo) {
- switch (llvm::Triple(llvm::Triple::normalize(lo._target)).getArch()) {
+
+std::unique_ptr<ELFTargetInfo> ELFTargetInfo::create(llvm::Triple triple) {
+ switch (triple.getArch()) {
case llvm::Triple::x86:
- return std::unique_ptr<ELFTargetInfo>(new lld::elf::X86TargetInfo(lo));
+ return std::unique_ptr<ELFTargetInfo>(new lld::elf::X86TargetInfo(triple));
case llvm::Triple::x86_64:
return std::unique_ptr<
- ELFTargetInfo>(new lld::elf::X86_64TargetInfo(lo));
+ ELFTargetInfo>(new lld::elf::X86_64TargetInfo(triple));
case llvm::Triple::hexagon:
return std::unique_ptr<
- ELFTargetInfo>(new lld::elf::HexagonTargetInfo(lo));
+ ELFTargetInfo>(new lld::elf::HexagonTargetInfo(triple));
case llvm::Triple::ppc:
- return std::unique_ptr<ELFTargetInfo>(new lld::elf::PPCTargetInfo(lo));
+ return std::unique_ptr<ELFTargetInfo>(new lld::elf::PPCTargetInfo(triple));
default:
return std::unique_ptr<ELFTargetInfo>();
}
}
-StringRef ELFTargetInfo::getEntry() const {
- if (!_options._entrySymbol.empty())
- return _options._entrySymbol;
- return "_start";
+bool ELFTargetInfo::appendLibrary(StringRef libName) {
+ SmallString<128> fullPath;
+ for (StringRef dir : _inputSearchPaths) {
+ // FIXME: need to handle other extensions, like .so
+ fullPath.assign(dir);
+ llvm::sys::path::append(fullPath, Twine("lib") + libName + ".a");
+ StringRef pathref = fullPath.str();
+ unsigned pathlen = pathref.size();
+ if (llvm::sys::fs::exists(pathref)) {
+ char *x = _extraStrings.Allocate<char>(pathlen);
+ memcpy(x, pathref.data(), pathlen);
+ appendInputFile(StringRef(x,pathlen));
+ return false;
+ }
+ }
+ return true;
}
} // end namespace lld
diff --git a/lld/lib/ReaderWriter/ELF/ExecutableAtoms.h b/lld/lib/ReaderWriter/ELF/ExecutableAtoms.h
index 4216cd5fb5b..d2ecbb2a903 100644
--- a/lld/lib/ReaderWriter/ELF/ExecutableAtoms.h
+++ b/lld/lib/ReaderWriter/ELF/ExecutableAtoms.h
@@ -49,6 +49,7 @@ public:
/// \brief add an undefined atom
virtual void addUndefinedAtom(StringRef symbolName) {
+ assert(!symbolName.empty() && "UndefinedAtoms must have a name");
Elf_Sym *symbol = new (_allocator) Elf_Sym;
symbol->st_name = 0;
symbol->st_value = 0;
diff --git a/lld/lib/ReaderWriter/ELF/ExecutableWriter.h b/lld/lib/ReaderWriter/ELF/ExecutableWriter.h
index fc0bde043b8..6bc283d701d 100644
--- a/lld/lib/ReaderWriter/ELF/ExecutableWriter.h
+++ b/lld/lib/ReaderWriter/ELF/ExecutableWriter.h
@@ -46,7 +46,7 @@ private:
/// absolute symbols
template<class ELFT>
void ExecutableWriter<ELFT>::addDefaultAtoms() {
- _runtimeFile.addUndefinedAtom(this->_targetInfo.getEntry());
+ _runtimeFile.addUndefinedAtom(this->_targetInfo.entrySymbolName());
_runtimeFile.addAbsoluteAtom("__bss_start");
_runtimeFile.addAbsoluteAtom("__bss_end");
_runtimeFile.addAbsoluteAtom("_end");
diff --git a/lld/lib/ReaderWriter/ELF/File.h b/lld/lib/ReaderWriter/ELF/File.h
index cbc2fff9895..a4c712420c9 100644
--- a/lld/lib/ReaderWriter/ELF/File.h
+++ b/lld/lib/ReaderWriter/ELF/File.h
@@ -143,7 +143,7 @@ public:
// Sections that have merge string property
std::vector<const Elf_Shdr *> mergeStringSections;
- bool doStringsMerge = _elfTargetInfo.getLinkerOptions()._mergeCommonStrings;
+ bool doStringsMerge = _elfTargetInfo.mergeCommonStrings();
// Handle: SHT_REL and SHT_RELA sections:
// Increment over the sections, when REL/RELA section types are found add
diff --git a/lld/lib/ReaderWriter/ELF/HeaderChunks.h b/lld/lib/ReaderWriter/ELF/HeaderChunks.h
index fe8efddfb0d..64400dc26d0 100644
--- a/lld/lib/ReaderWriter/ELF/HeaderChunks.h
+++ b/lld/lib/ReaderWriter/ELF/HeaderChunks.h
@@ -18,6 +18,7 @@
#include "llvm/Support/ELF.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FileOutputBuffer.h"
+#include "llvm/Support/Format.h"
/// \brief An Header represents the Elf[32/64]_Ehdr structure at the
/// start of an ELF executable file.
@@ -98,10 +99,10 @@ public:
FindPhdr(uint64_t type, uint64_t flags, uint64_t flagsClear)
: _type(type)
, _flags(flags)
- , _flagsClear(flagsClear)
- {}
+ , _flagsClear(flagsClear) {
+ }
- bool operator()(const Elf_Phdr *j) const {
+ bool operator()(const llvm::object::Elf_Phdr_Impl<ELFT> *j) const {
return ((j->p_type == _type) &&
((j->p_flags & _flags) == _flags) &&
(!(j->p_flags & _flagsClear)));
diff --git a/lld/lib/ReaderWriter/ELF/Hexagon/HexagonRelocationFunctions.h b/lld/lib/ReaderWriter/ELF/Hexagon/HexagonRelocationFunctions.h
index b0ee2e440e9..a02caa74595 100644
--- a/lld/lib/ReaderWriter/ELF/Hexagon/HexagonRelocationFunctions.h
+++ b/lld/lib/ReaderWriter/ELF/Hexagon/HexagonRelocationFunctions.h
@@ -29,7 +29,8 @@ typedef struct {
sizeof(insn_encodings_v4) / sizeof(Instruction))
/// \brief finds the scatter Bits that need to be used to apply relocations
-uint32_t findBitMask(uint32_t insn, Instruction *encodings, int32_t numInsns) {
+inline uint32_t
+findBitMask(uint32_t insn, Instruction *encodings, int32_t numInsns) {
for (int32_t i = 0; i < numInsns ; i++) {
if (((insn & 0xc000) == 0) && !(encodings[i].isDuplex))
continue;
diff --git a/lld/lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.cpp b/lld/lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.cpp
index d7c15d410a3..cc928e6b379 100644
--- a/lld/lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.cpp
+++ b/lld/lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.cpp
@@ -212,8 +212,7 @@ public:
} // end anonymous namespace
void elf::HexagonTargetInfo::addPasses(PassManager &pm) const {
- if (_options._outputKind == OutputKind::DynamicExecutable ||
- _options._outputKind == OutputKind::Shared)
+ if (isDynamic())
pm.add(std::unique_ptr<Pass>(new DynamicGOTPLTPass(*this)));
ELFTargetInfo::addPasses(pm);
}
diff --git a/lld/lib/ReaderWriter/ELF/Hexagon/HexagonTargetInfo.cpp b/lld/lib/ReaderWriter/ELF/Hexagon/HexagonTargetInfo.cpp
index ddba886525d..49d91434fde 100644
--- a/lld/lib/ReaderWriter/ELF/Hexagon/HexagonTargetInfo.cpp
+++ b/lld/lib/ReaderWriter/ELF/Hexagon/HexagonTargetInfo.cpp
@@ -22,8 +22,8 @@ using namespace lld;
#define LLD_CASE(name) .Case(#name, llvm::ELF::name)
-ErrorOr<int32_t> elf::HexagonTargetInfo::relocKindFromString(
- StringRef str) const {
+ErrorOr<Reference::Kind>
+elf::HexagonTargetInfo::relocKindFromString(StringRef str) const {
int32_t ret = llvm::StringSwitch<int32_t>(str)
LLD_CASE(R_HEX_NONE)
LLD_CASE(R_HEX_B22_PCREL)
diff --git a/lld/lib/ReaderWriter/ELF/Hexagon/HexagonTargetInfo.h b/lld/lib/ReaderWriter/ELF/Hexagon/HexagonTargetInfo.h
index ca8fb94d30d..82f4c6b5ce5 100644
--- a/lld/lib/ReaderWriter/ELF/Hexagon/HexagonTargetInfo.h
+++ b/lld/lib/ReaderWriter/ELF/Hexagon/HexagonTargetInfo.h
@@ -12,7 +12,6 @@
#include "HexagonTargetHandler.h"
-#include "lld/Core/LinkerOptions.h"
#include "lld/ReaderWriter/ELFTargetInfo.h"
#include "llvm/Object/ELF.h"
@@ -23,15 +22,14 @@ namespace elf {
class HexagonTargetInfo LLVM_FINAL : public ELFTargetInfo {
public:
- HexagonTargetInfo(const LinkerOptions &lo) : ELFTargetInfo(lo) {
+ HexagonTargetInfo(llvm::Triple triple)
+ : ELFTargetInfo(triple) {
_targetHandler = std::unique_ptr<TargetHandlerBase>(
new HexagonTargetHandler(*this));
}
- virtual uint64_t getPageSize() const { return 0x1000; }
-
- virtual ErrorOr<int32_t> relocKindFromString(StringRef str) const;
- virtual ErrorOr<std::string> stringFromRelocKind(int32_t kind) const;
+ virtual ErrorOr<Reference::Kind> relocKindFromString(StringRef str) const;
+ virtual ErrorOr<std::string> stringFromRelocKind(Reference::Kind kind) const;
virtual void addPasses(PassManager &) const;
diff --git a/lld/lib/ReaderWriter/ELF/OutputELFWriter.h b/lld/lib/ReaderWriter/ELF/OutputELFWriter.h
index 2cc81dd1462..40f14bb5f03 100644
--- a/lld/lib/ReaderWriter/ELF/OutputELFWriter.h
+++ b/lld/lib/ReaderWriter/ELF/OutputELFWriter.h
@@ -345,7 +345,7 @@ error_code OutputELFWriter<ELFT>::writeFile(const File &file, StringRef path) {
_Header->e_shnum(_shdrtab->numHeaders());
_Header->e_shstrndx(_shstrtab->ordinal());
uint64_t virtualAddr = 0;
- _layout->findAtomAddrByName(_targetInfo.getEntry(), virtualAddr);
+ _layout->findAtomAddrByName(_targetInfo.entrySymbolName(), virtualAddr);
_Header->e_entry(virtualAddr);
// HACK: We have to write out the header and program header here even though
diff --git a/lld/lib/ReaderWriter/ELF/PPC/PPCTargetInfo.cpp b/lld/lib/ReaderWriter/ELF/PPC/PPCTargetInfo.cpp
index e69de29bb2d..337b02f4c2a 100644
--- a/lld/lib/ReaderWriter/ELF/PPC/PPCTargetInfo.cpp
+++ b/lld/lib/ReaderWriter/ELF/PPC/PPCTargetInfo.cpp
@@ -0,0 +1,36 @@
+#include "PPCTargetInfo.h"
+
+#include "lld/Core/LLVM.h"
+
+#include "llvm/ADT/StringSwitch.h"
+#include "llvm/Support/ErrorOr.h"
+
+using namespace lld;
+
+#define LLD_CASE(name) .Case(#name, llvm::ELF::name)
+
+ErrorOr<Reference::Kind> elf::PPCTargetInfo::relocKindFromString(
+ StringRef str) const {
+ int32_t ret = llvm::StringSwitch<int32_t>(str)
+ LLD_CASE(R_PPC_NONE)
+ LLD_CASE(R_PPC_ADDR32)
+ .Default(-1);
+
+ if (ret == -1)
+ return make_error_code(yaml_reader_error::illegal_value);
+ return ret;
+}
+
+#undef LLD_CASE
+
+#define LLD_CASE(name) case llvm::ELF::name: return std::string(#name);
+
+ErrorOr<std::string>
+elf::PPCTargetInfo::stringFromRelocKind(Reference::Kind kind) const {
+ switch (kind) {
+ LLD_CASE(R_PPC_NONE)
+ LLD_CASE(R_PPC_ADDR32)
+ }
+
+ return make_error_code(yaml_reader_error::illegal_value);
+}
diff --git a/lld/lib/ReaderWriter/ELF/PPC/PPCTargetInfo.h b/lld/lib/ReaderWriter/ELF/PPC/PPCTargetInfo.h
index 97ba655d4ab..077767695c9 100644
--- a/lld/lib/ReaderWriter/ELF/PPC/PPCTargetInfo.h
+++ b/lld/lib/ReaderWriter/ELF/PPC/PPCTargetInfo.h
@@ -12,7 +12,6 @@
#include "PPCTargetHandler.h"
-#include "lld/Core/LinkerOptions.h"
#include "lld/ReaderWriter/ELFTargetInfo.h"
#include "llvm/Object/ELF.h"
@@ -22,14 +21,15 @@ namespace lld {
namespace elf {
class PPCTargetInfo LLVM_FINAL : public ELFTargetInfo {
public:
- PPCTargetInfo(const LinkerOptions &lo) : ELFTargetInfo(lo) {
+ PPCTargetInfo(llvm::Triple triple)
+ : ELFTargetInfo(triple) {
_targetHandler = std::unique_ptr<TargetHandlerBase>(
new PPCTargetHandler(*this));
}
virtual bool isLittleEndian() const { return false; }
-
- virtual uint64_t getPageSize() const { return 0x1000; }
+ virtual ErrorOr<Reference::Kind> relocKindFromString(StringRef str) const;
+ virtual ErrorOr<std::string> stringFromRelocKind(Reference::Kind kind) const;
};
} // elf
diff --git a/lld/lib/ReaderWriter/ELF/Reader.cpp b/lld/lib/ReaderWriter/ELF/Reader.cpp
index be2fedb239b..cb6e9cde00f 100644
--- a/lld/lib/ReaderWriter/ELF/Reader.cpp
+++ b/lld/lib/ReaderWriter/ELF/Reader.cpp
@@ -78,12 +78,12 @@ namespace elf {
/// memory buffer for ELF class and bit width
class ELFReader : public Reader {
public:
- ELFReader(const ELFTargetInfo &ti, std::function<ReaderFunc> read)
- : lld::Reader(ti), _elfTargetInfo(ti), _readerArchive(ti, read) {
+ ELFReader(const ELFTargetInfo &ti)
+ : lld::Reader(ti), _elfTargetInfo(ti), _readerArchive(ti, *this) {
}
- error_code parseFile(std::unique_ptr<MemoryBuffer> mb,
- std::vector<std::unique_ptr<File> > &result) {
+ error_code parseFile(std::unique_ptr<MemoryBuffer> &mb,
+ std::vector<std::unique_ptr<File> > &result) const {
using llvm::object::ELFType;
llvm::sys::LLVMFileType fileType =
llvm::sys::IdentifyFileType(mb->getBufferStart(),
@@ -112,10 +112,10 @@ public:
break;
}
case llvm::sys::Archive_FileType:
- ec = _readerArchive.parseFile(std::move(mb), result);
+ ec = _readerArchive.parseFile(mb, result);
break;
default:
- llvm_unreachable("not supported format");
+ return llvm::make_error_code(llvm::errc::executable_format_error);
break;
}
@@ -131,8 +131,7 @@ private:
};
} // end namespace elf
-std::unique_ptr<Reader> createReaderELF(const ELFTargetInfo &eti,
- std::function<ReaderFunc> read) {
- return std::unique_ptr<Reader>(new elf::ELFReader(eti, std::move(read)));
+std::unique_ptr<Reader> createReaderELF(const ELFTargetInfo &targetinfo) {
+ return std::unique_ptr<Reader>(new elf::ELFReader(targetinfo));
}
} // end namespace lld
diff --git a/lld/lib/ReaderWriter/ELF/SectionChunks.h b/lld/lib/ReaderWriter/ELF/SectionChunks.h
index 2bca266fe2d..8237529629f 100644
--- a/lld/lib/ReaderWriter/ELF/SectionChunks.h
+++ b/lld/lib/ReaderWriter/ELF/SectionChunks.h
@@ -603,13 +603,13 @@ public:
/// \brief Get the symbol table index for an Atom. If it's not in the symbol
/// table, return STN_UNDEF.
uint32_t getSymbolTableIndex(const Atom *a) const {
- auto se = std::find_if(_symbolTable.begin(), _symbolTable.end(),
+ auto entry = std::find_if(_symbolTable.begin(), _symbolTable.end(),
[=](const SymbolEntry &se) {
return se._atom == a;
});
- if (se == _symbolTable.end())
+ if (entry == _symbolTable.end())
return STN_UNDEF;
- return std::distance(_symbolTable.begin(), se);
+ return std::distance(_symbolTable.begin(), entry);
}
virtual void finalize() { finalize(true); }
diff --git a/lld/lib/ReaderWriter/ELF/TargetHandler.h b/lld/lib/ReaderWriter/ELF/TargetHandler.h
index ebdb203c0da..ab30c3636e7 100644
--- a/lld/lib/ReaderWriter/ELF/TargetHandler.h
+++ b/lld/lib/ReaderWriter/ELF/TargetHandler.h
@@ -19,7 +19,6 @@
#include "Layout.h"
#include "lld/Core/InputFiles.h"
-#include "lld/Core/LinkerOptions.h"
#include "lld/Core/LLVM.h"
#include "lld/Core/TargetInfo.h"
#include "lld/ReaderWriter/ELFTargetInfo.h"
diff --git a/lld/lib/ReaderWriter/ELF/Writer.cpp b/lld/lib/ReaderWriter/ELF/Writer.cpp
index 6e2744ea1f3..a174ef0c051 100644
--- a/lld/lib/ReaderWriter/ELF/Writer.cpp
+++ b/lld/lib/ReaderWriter/ELF/Writer.cpp
@@ -1,4 +1,4 @@
-//===- lib/ReaderWriter/ELF/Writer.cpp ------------------------------------===//
+//===- lib/ReaderWriter/ELF/WriterELF.cpp ---------------------------------===//
//
// The LLVM Linker
//
@@ -6,53 +6,63 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-#include "ExecutableWriter.h"
+
+#include "lld/ReaderWriter/Writer.h"
+
#include "DynamicLibraryWriter.h"
+#include "ExecutableWriter.h"
+
using namespace llvm;
using namespace llvm::object;
-
namespace lld {
-std::unique_ptr<Writer> createWriterELF(const ELFTargetInfo &TI) {
+std::unique_ptr<Writer> createWriterELF(const ELFTargetInfo &info) {
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
- const LinkerOptions &options = TI.getLinkerOptions();
-
- if ((options._outputKind == OutputKind::StaticExecutable) ||
- (options._outputKind == OutputKind::DynamicExecutable)) {
- if (!TI.is64Bits() && TI.isLittleEndian())
- return std::unique_ptr<Writer>(new
- elf::ExecutableWriter<ELFType<support::little, 4, false>>(TI));
- else if (TI.is64Bits() && TI.isLittleEndian())
- return std::unique_ptr<Writer>(new
- elf::ExecutableWriter<ELFType<support::little, 8, true>>(TI));
- else if (!TI.is64Bits() && !TI.isLittleEndian())
- return std::unique_ptr<Writer>(new
- elf::ExecutableWriter<ELFType<support::big, 4, false>>(TI));
- else if (TI.is64Bits() && !TI.isLittleEndian())
- return std::unique_ptr<Writer>(new
- elf::ExecutableWriter<ELFType<support::big, 8, true>>(TI));
- llvm_unreachable("Invalid Options!");
- } else if (options._outputKind == OutputKind::Shared) {
- if (!TI.is64Bits() && TI.isLittleEndian())
- return std::unique_ptr<Writer>(new
- elf::DynamicLibraryWriter<ELFType<support::little, 4, false>>(TI));
- else if (TI.is64Bits() && TI.isLittleEndian())
- return std::unique_ptr<Writer>(new
- elf::DynamicLibraryWriter<ELFType<support::little, 8, true>>(TI));
- else if (!TI.is64Bits() && !TI.isLittleEndian())
- return std::unique_ptr<Writer>(new
- elf::DynamicLibraryWriter<ELFType<support::big, 4, false>>(TI));
- else if (TI.is64Bits() && !TI.isLittleEndian())
- return std::unique_ptr<Writer>(new
- elf::DynamicLibraryWriter<ELFType<support::big, 8, true>>(TI));
- llvm_unreachable("Invalid Options!");
+ switch(info.getOutputType()) {
+ case llvm::ELF::ET_EXEC:
+ if (info.is64Bits()) {
+ if (info.isLittleEndian())
+ return std::unique_ptr<Writer>(new
+ elf::ExecutableWriter<ELFType<support::little, 8, true>>(info));
+ else
+ return std::unique_ptr<Writer>(new
+ elf::ExecutableWriter<ELFType<support::big, 8, true>>(info));
+ } else {
+ if (info.isLittleEndian())
+ return std::unique_ptr<Writer>(new
+ elf::ExecutableWriter<ELFType<support::little, 4, false>>(info));
+ else
+ return std::unique_ptr<Writer>(new
+ elf::ExecutableWriter<ELFType<support::big, 4, false>>(info));
+ }
+ break;
+ case llvm::ELF::ET_DYN:
+ if (info.is64Bits()) {
+ if (info.isLittleEndian())
+ return std::unique_ptr<Writer>(new
+ elf::DynamicLibraryWriter<ELFType<support::little, 8, true>>(info));
+ else
+ return std::unique_ptr<Writer>(new
+ elf::DynamicLibraryWriter<ELFType<support::big, 8, true>>(info));
+ } else {
+ if (info.isLittleEndian())
+ return std::unique_ptr<Writer>(new
+ elf::DynamicLibraryWriter<ELFType<support::little, 4, false>>(info));
+ else
+ return std::unique_ptr<Writer>(new
+ elf::DynamicLibraryWriter<ELFType<support::big, 4, false>>(info));
+ }
+ break;
+ case llvm::ELF::ET_REL:
+ llvm_unreachable("TODO: support -r mode");
+ default:
+ llvm_unreachable("unsupported output type");
}
- else
- llvm_unreachable("unsupported options");
-}
}
+
+} // namespace lld
diff --git a/lld/lib/ReaderWriter/ELF/Writer.h b/lld/lib/ReaderWriter/ELF/Writer.h
index 7e67c31369d..20b330ed739 100644
--- a/lld/lib/ReaderWriter/ELF/Writer.h
+++ b/lld/lib/ReaderWriter/ELF/Writer.h
@@ -28,7 +28,7 @@ public:
virtual void buildChunks(const File &file) = 0;
/// \brief Writes the chunks into the output file specified by path
- virtual error_code writeFile(const File &File, StringRef path) = 0;
+ virtual error_code writeFile(const File &file, StringRef path) = 0;
/// \brief Get the virtual address of \p atom after layout.
virtual uint64_t addressOfAtom(const Atom *atom) = 0;
diff --git a/lld/lib/ReaderWriter/ELF/X86/X86TargetInfo.cpp b/lld/lib/ReaderWriter/ELF/X86/X86TargetInfo.cpp
index e69de29bb2d..8a0737c5fc8 100644
--- a/lld/lib/ReaderWriter/ELF/X86/X86TargetInfo.cpp
+++ b/lld/lib/ReaderWriter/ELF/X86/X86TargetInfo.cpp
@@ -0,0 +1,36 @@
+#include "X86TargetInfo.h"
+
+#include "lld/Core/LLVM.h"
+
+#include "llvm/ADT/StringSwitch.h"
+#include "llvm/Support/ErrorOr.h"
+
+using namespace lld;
+
+#define LLD_CASE(name) .Case(#name, llvm::ELF::name)
+
+ErrorOr<Reference::Kind> elf::X86TargetInfo::relocKindFromString(
+ StringRef str) const {
+ int32_t ret = llvm::StringSwitch<int32_t>(str)
+ LLD_CASE(R_386_NONE)
+ LLD_CASE(R_386_PC32)
+ .Default(-1);
+
+ if (ret == -1)
+ return make_error_code(yaml_reader_error::illegal_value);
+ return ret;
+}
+
+#undef LLD_CASE
+
+#define LLD_CASE(name) case llvm::ELF::name: return std::string(#name);
+
+ErrorOr<std::string>
+elf::X86TargetInfo::stringFromRelocKind(Reference::Kind kind) const {
+ switch (kind) {
+ LLD_CASE(R_386_NONE)
+ LLD_CASE(R_386_PC32)
+ }
+
+ return make_error_code(yaml_reader_error::illegal_value);
+}
diff --git a/lld/lib/ReaderWriter/ELF/X86/X86TargetInfo.h b/lld/lib/ReaderWriter/ELF/X86/X86TargetInfo.h
index c66a42f78d6..00007afbdf0 100644
--- a/lld/lib/ReaderWriter/ELF/X86/X86TargetInfo.h
+++ b/lld/lib/ReaderWriter/ELF/X86/X86TargetInfo.h
@@ -12,7 +12,6 @@
#include "X86TargetHandler.h"
-#include "lld/Core/LinkerOptions.h"
#include "lld/ReaderWriter/ELFTargetInfo.h"
#include "llvm/Object/ELF.h"
@@ -22,12 +21,14 @@ namespace lld {
namespace elf {
class X86TargetInfo LLVM_FINAL : public ELFTargetInfo {
public:
- X86TargetInfo(const LinkerOptions &lo) : ELFTargetInfo(lo) {
+ X86TargetInfo(llvm::Triple triple)
+ : ELFTargetInfo(triple) {
_targetHandler = std::unique_ptr<TargetHandlerBase>(
new X86TargetHandler(*this));
}
- virtual uint64_t getPageSize() const { return 0x1000; }
+ virtual ErrorOr<Reference::Kind> relocKindFromString(StringRef str) const;
+ virtual ErrorOr<std::string> stringFromRelocKind(Reference::Kind kind) const;
};
} // end namespace elf
} // end namespace lld
diff --git a/lld/lib/ReaderWriter/ELF/X86_64/X86_64TargetInfo.cpp b/lld/lib/ReaderWriter/ELF/X86_64/X86_64TargetInfo.cpp
index bb6236e109e..cad8dd2809f 100644
--- a/lld/lib/ReaderWriter/ELF/X86_64/X86_64TargetInfo.cpp
+++ b/lld/lib/ReaderWriter/ELF/X86_64/X86_64TargetInfo.cpp
@@ -399,18 +399,29 @@ public:
} // end anon namespace
void elf::X86_64TargetInfo::addPasses(PassManager &pm) const {
- if (_options._outputKind == OutputKind::StaticExecutable)
- pm.add(std::unique_ptr<Pass>(new StaticGOTPLTPass(*this)));
- else if (_options._outputKind == OutputKind::DynamicExecutable ||
- _options._outputKind == OutputKind::Shared)
+ switch (_outputFileType) {
+ case llvm::ELF::ET_EXEC:
+ if (_isStaticExecutable)
+ pm.add(std::unique_ptr<Pass>(new StaticGOTPLTPass(*this)));
+ else
+ pm.add(std::unique_ptr<Pass>(new DynamicGOTPLTPass(*this)));
+ break;
+ case llvm::ELF::ET_DYN:
pm.add(std::unique_ptr<Pass>(new DynamicGOTPLTPass(*this)));
+ break;
+ case llvm::ELF::ET_REL:
+ break;
+ default:
+ llvm_unreachable("Unhandled output file type");
+ }
ELFTargetInfo::addPasses(pm);
}
+
#define LLD_CASE(name) .Case(#name, llvm::ELF::name)
-ErrorOr<int32_t> elf::X86_64TargetInfo::relocKindFromString(
- StringRef str) const {
+ErrorOr<Reference::Kind>
+elf::X86_64TargetInfo::relocKindFromString(StringRef str) const {
int32_t ret = llvm::StringSwitch<int32_t>(str)
LLD_CASE(R_X86_64_NONE)
LLD_CASE(R_X86_64_64)
@@ -462,8 +473,8 @@ ErrorOr<int32_t> elf::X86_64TargetInfo::relocKindFromString(
#define LLD_CASE(name) case llvm::ELF::name: return std::string(#name);
-ErrorOr<std::string> elf::X86_64TargetInfo::stringFromRelocKind(
- int32_t kind) const {
+ErrorOr<std::string>
+elf::X86_64TargetInfo::stringFromRelocKind(Reference::Kind kind) const {
switch (kind) {
LLD_CASE(R_X86_64_NONE)
LLD_CASE(R_X86_64_64)
diff --git a/lld/lib/ReaderWriter/ELF/X86_64/X86_64TargetInfo.h b/lld/lib/ReaderWriter/ELF/X86_64/X86_64TargetInfo.h
index 11adab4ecfc..4c8afa065df 100644
--- a/lld/lib/ReaderWriter/ELF/X86_64/X86_64TargetInfo.h
+++ b/lld/lib/ReaderWriter/ELF/X86_64/X86_64TargetInfo.h
@@ -12,7 +12,6 @@
#include "X86_64TargetHandler.h"
-#include "lld/Core/LinkerOptions.h"
#include "lld/ReaderWriter/ELFTargetInfo.h"
#include "llvm/Object/ELF.h"
@@ -29,19 +28,18 @@ enum {
class X86_64TargetInfo LLVM_FINAL : public ELFTargetInfo {
public:
- X86_64TargetInfo(const LinkerOptions &lo) : ELFTargetInfo(lo) {
+ X86_64TargetInfo(llvm::Triple triple)
+ : ELFTargetInfo(triple) {
_targetHandler =
std::unique_ptr<TargetHandlerBase>(new X86_64TargetHandler(*this));
}
- virtual uint64_t getPageSize() const { return 0x1000; }
-
virtual void addPasses(PassManager &) const;
virtual uint64_t getBaseAddress() const {
- if (_options._baseAddress == 0)
+ if (_baseAddress == 0)
return 0x400000;
- return _options._baseAddress;
+ return _baseAddress;
}
virtual bool isDynamicRelocation(const DefinedAtom &,
@@ -66,8 +64,8 @@ public:
}
}
- virtual ErrorOr<int32_t> relocKindFromString(StringRef str) const;
- virtual ErrorOr<std::string> stringFromRelocKind(int32_t kind) const;
+ virtual ErrorOr<Reference::Kind> relocKindFromString(StringRef str) const;
+ virtual ErrorOr<std::string> stringFromRelocKind(Reference::Kind kind) const;
};
} // end namespace elf
OpenPOWER on IntegriCloud