summaryrefslogtreecommitdiff
path: root/lib/Core
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Core')
-rw-r--r--lib/Core/DefinedAtom.cpp1
-rw-r--r--lib/Core/Error.cpp52
-rw-r--r--lib/Core/File.cpp8
-rw-r--r--lib/Core/LinkingContext.cpp8
-rw-r--r--lib/Core/Makefile13
-rw-r--r--lib/Core/Reader.cpp16
-rw-r--r--lib/Core/Resolver.cpp57
-rw-r--r--lib/Core/SymbolTable.cpp13
-rw-r--r--lib/Core/TODO.txt18
-rw-r--r--lib/Core/Writer.cpp4
10 files changed, 83 insertions, 107 deletions
diff --git a/lib/Core/DefinedAtom.cpp b/lib/Core/DefinedAtom.cpp
index b3f81ca65a91..f1d308088ed4 100644
--- a/lib/Core/DefinedAtom.cpp
+++ b/lib/Core/DefinedAtom.cpp
@@ -76,6 +76,7 @@ DefinedAtom::ContentPermissions DefinedAtom::permissions(ContentType type) {
case typeGnuLinkOnce:
case typeUnknown:
case typeTempLTO:
+ case typeSectCreate:
return permUnknown;
}
llvm_unreachable("unknown content type");
diff --git a/lib/Core/Error.cpp b/lib/Core/Error.cpp
index 24809c3869e5..3b7733746dcd 100644
--- a/lib/Core/Error.cpp
+++ b/lib/Core/Error.cpp
@@ -16,39 +16,6 @@
using namespace lld;
-class _NativeReaderErrorCategory : public std::error_category {
-public:
- const char* name() const LLVM_NOEXCEPT override {
- return "lld.native.reader";
- }
-
- std::string message(int ev) const override {
- switch (static_cast<NativeReaderError>(ev)) {
- case NativeReaderError::success:
- return "Success";
- case NativeReaderError::unknown_file_format:
- return "Unknown file format";
- case NativeReaderError::file_too_short:
- return "file truncated";
- case NativeReaderError::file_malformed:
- return "file malformed";
- case NativeReaderError::memory_error:
- return "out of memory";
- case NativeReaderError::unknown_chunk_type:
- return "unknown chunk type";
- case NativeReaderError::conflicting_target_machine:
- return "conflicting target machine";
- }
- llvm_unreachable("An enumerator of NativeReaderError does not have a "
- "message defined.");
- }
-};
-
-const std::error_category &lld::native_reader_category() {
- static _NativeReaderErrorCategory o;
- return o;
-}
-
class _YamlReaderErrorCategory : public std::error_category {
public:
const char* name() const LLVM_NOEXCEPT override {
@@ -57,8 +24,6 @@ public:
std::string message(int ev) const override {
switch (static_cast<YamlReaderError>(ev)) {
- case YamlReaderError::success:
- return "Success";
case YamlReaderError::unknown_keyword:
return "Unknown keyword found in yaml file";
case YamlReaderError::illegal_value:
@@ -91,6 +56,14 @@ public:
case LinkerScriptReaderError::unrecognized_function_in_expr:
return "Unrecognized function call when evaluating linker script "
"expression";
+ case LinkerScriptReaderError::unknown_phdr_ids:
+ return "Unknown header identifiers (missing in PHDRS command) are used";
+ case LinkerScriptReaderError::extra_program_phdr:
+ return "Extra program header is found";
+ case LinkerScriptReaderError::misplaced_program_phdr:
+ return "Program header must precede load segments";
+ case LinkerScriptReaderError::program_phdr_wrong_phdrs:
+ return "Program header has invalid PHDRS attribute";
}
llvm_unreachable("An enumerator of LinkerScriptReaderError does not have a "
"message defined.");
@@ -102,7 +75,6 @@ const std::error_category &lld::LinkerScriptReaderCategory() {
return o;
}
-
namespace lld {
/// Temporary class to enable make_dynamic_error_code() until
@@ -110,7 +82,7 @@ namespace lld {
/// other than error_code.
class dynamic_error_category : public std::error_category {
public:
- ~dynamic_error_category() LLVM_NOEXCEPT {}
+ ~dynamic_error_category() override = default;
const char *name() const LLVM_NOEXCEPT override {
return "lld.dynamic_error";
@@ -140,6 +112,10 @@ private:
static dynamic_error_category categorySingleton;
+std::error_code make_dynamic_error_code(const char *msg) {
+ return make_dynamic_error_code(StringRef(msg));
+}
+
std::error_code make_dynamic_error_code(StringRef msg) {
return std::error_code(categorySingleton.add(msg), categorySingleton);
}
@@ -148,4 +124,4 @@ std::error_code make_dynamic_error_code(const Twine &msg) {
return std::error_code(categorySingleton.add(msg.str()), categorySingleton);
}
-}
+} // namespace lld
diff --git a/lib/Core/File.cpp b/lib/Core/File.cpp
index dbac86b368aa..ac95f1016797 100644
--- a/lib/Core/File.cpp
+++ b/lib/Core/File.cpp
@@ -15,10 +15,10 @@ namespace lld {
File::~File() {}
-File::atom_collection_empty<DefinedAtom> File::_noDefinedAtoms;
-File::atom_collection_empty<UndefinedAtom> File::_noUndefinedAtoms;
-File::atom_collection_empty<SharedLibraryAtom> File::_noSharedLibraryAtoms;
-File::atom_collection_empty<AbsoluteAtom> File::_noAbsoluteAtoms;
+File::AtomVector<DefinedAtom> File::_noDefinedAtoms;
+File::AtomVector<UndefinedAtom> File::_noUndefinedAtoms;
+File::AtomVector<SharedLibraryAtom> File::_noSharedLibraryAtoms;
+File::AtomVector<AbsoluteAtom> File::_noAbsoluteAtoms;
std::error_code File::parse() {
std::lock_guard<std::mutex> lock(_parseMutex);
diff --git a/lib/Core/LinkingContext.cpp b/lib/Core/LinkingContext.cpp
index c6656b935916..cbcf25c17df2 100644
--- a/lib/Core/LinkingContext.cpp
+++ b/lib/Core/LinkingContext.cpp
@@ -24,7 +24,7 @@ LinkingContext::LinkingContext()
_warnIfCoalesableAtomsHaveDifferentCanBeNull(false),
_warnIfCoalesableAtomsHaveDifferentLoadName(false),
_printRemainingUndefines(true), _allowRemainingUndefines(false),
- _logInputFiles(false), _allowShlibUndefines(false),
+ _logInputFiles(false), _allowShlibUndefines(true),
_outputFileType(OutputFileType::Default), _nextOrdinal(0) {}
LinkingContext::~LinkingContext() {}
@@ -37,9 +37,9 @@ std::error_code LinkingContext::writeFile(const File &linkedFile) const {
return this->writer().writeFile(linkedFile, _outputPath);
}
-bool LinkingContext::createImplicitFiles(
- std::vector<std::unique_ptr<File> > &result) {
- return this->writer().createImplicitFiles(result);
+void LinkingContext::createImplicitFiles(
+ std::vector<std::unique_ptr<File>> &result) {
+ this->writer().createImplicitFiles(result);
}
std::unique_ptr<File> LinkingContext::createEntrySymbolFile() const {
diff --git a/lib/Core/Makefile b/lib/Core/Makefile
deleted file mode 100644
index 042d01a1e1b3..000000000000
--- a/lib/Core/Makefile
+++ /dev/null
@@ -1,13 +0,0 @@
-##===- lld/lib/Core/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 := lldCore
-
-include $(LLD_LEVEL)/Makefile
diff --git a/lib/Core/Reader.cpp b/lib/Core/Reader.cpp
index 6f8b8cbd1bf8..6069093d211e 100644
--- a/lib/Core/Reader.cpp
+++ b/lib/Core/Reader.cpp
@@ -13,7 +13,6 @@
#include "llvm/Support/Errc.h"
#include "llvm/Support/FileUtilities.h"
#include "llvm/Support/MemoryBuffer.h"
-#include "llvm/Support/Path.h"
#include <memory>
#include <system_error>
@@ -29,22 +28,17 @@ void Registry::add(std::unique_ptr<YamlIOTaggedDocumentHandler> handler) {
_yamlHandlers.push_back(std::move(handler));
}
-std::error_code
-Registry::loadFile(std::unique_ptr<MemoryBuffer> mb,
- std::vector<std::unique_ptr<File>> &result) const {
- // Get file type.
+ErrorOr<std::unique_ptr<File>>
+Registry::loadFile(std::unique_ptr<MemoryBuffer> mb) const {
+ // Get file magic.
StringRef content(mb->getBufferStart(), mb->getBufferSize());
llvm::sys::fs::file_magic fileType = llvm::sys::fs::identify_magic(content);
- // Get file extension.
- StringRef extension = llvm::sys::path::extension(mb->getBufferIdentifier());
// Ask each registered reader if it can handle this file type or extension.
for (const std::unique_ptr<Reader> &reader : _readers) {
- if (!reader->canParse(fileType, extension, *mb))
+ if (!reader->canParse(fileType, mb->getMemBufferRef()))
continue;
- if (std::error_code ec = reader->loadFile(std::move(mb), *this, result))
- return ec;
- return std::error_code();
+ return reader->loadFile(std::move(mb), *this);
}
// No Reader could parse this file.
diff --git a/lib/Core/Resolver.cpp b/lib/Core/Resolver.cpp
index 393a7ef2bfc8..8f89856c4a47 100644
--- a/lib/Core/Resolver.cpp
+++ b/lib/Core/Resolver.cpp
@@ -153,7 +153,6 @@ void Resolver::maybeAddSectionGroupOrGnuLinkOnce(const DefinedAtom &atom) {
llvm::errs() << "SymbolTable: error while merging " << atom.name()
<< "\n";
llvm::report_fatal_error("duplicate symbol error");
- return;
}
for (const Reference *r : atom) {
@@ -180,6 +179,8 @@ void Resolver::doDefinedAtom(const DefinedAtom &atom) {
<< atom.ordinal()
<< ", name="
<< atom.name()
+ << ", type="
+ << atom.contentType()
<< "\n");
// add to list of known atoms
@@ -295,11 +296,15 @@ void Resolver::updatePreloadArchiveMap() {
// Keep adding atoms until _ctx.getNextFile() returns an error. This
// function is where undefined atoms are resolved.
bool Resolver::resolveUndefines() {
+ DEBUG_WITH_TYPE("resolver",
+ llvm::dbgs() << "******** Resolving undefines:\n");
ScopedTask task(getDefaultDomain(), "resolveUndefines");
int index = 0;
std::set<File *> seen;
for (;;) {
bool undefAdded = false;
+ DEBUG_WITH_TYPE("resolver",
+ llvm::dbgs() << "Loading file #" << index << "\n");
File *file = getFile(index);
if (!file)
return true;
@@ -308,6 +313,8 @@ bool Resolver::resolveUndefines() {
<< ": " << ec.message() << "\n";
return false;
}
+ DEBUG_WITH_TYPE("resolver",
+ llvm::dbgs() << "Loaded file: " << file->path() << "\n");
file->beforeLink();
updatePreloadArchiveMap();
switch (file->kind()) {
@@ -340,6 +347,8 @@ bool Resolver::resolveUndefines() {
// switch all references to undefined or coalesced away atoms
// to the new defined atom
void Resolver::updateReferences() {
+ DEBUG_WITH_TYPE("resolver",
+ llvm::dbgs() << "******** Updating references:\n");
ScopedTask task(getDefaultDomain(), "updateReferences");
for (const Atom *atom : _atoms) {
if (const DefinedAtom *defAtom = dyn_cast<DefinedAtom>(atom)) {
@@ -388,6 +397,8 @@ static bool isBackref(const Reference *ref) {
// remove all atoms not actually used
void Resolver::deadStripOptimize() {
+ DEBUG_WITH_TYPE("resolver",
+ llvm::dbgs() << "******** Dead stripping unused atoms:\n");
ScopedTask task(getDefaultDomain(), "deadStripOptimize");
// only do this optimization with -dead_strip
if (!_ctx.deadStrip())
@@ -433,6 +444,9 @@ void Resolver::deadStripOptimize() {
// error out if some undefines remain
bool Resolver::checkUndefines() {
+ DEBUG_WITH_TYPE("resolver",
+ llvm::dbgs() << "******** Checking for undefines:\n");
+
// build vector of remaining undefined symbols
std::vector<const UndefinedAtom *> undefinedAtoms = _symbolTable.undefines();
if (_ctx.deadStrip()) {
@@ -479,6 +493,8 @@ bool Resolver::checkUndefines() {
// remove from _atoms all coaleseced away atoms
void Resolver::removeCoalescedAwayAtoms() {
+ DEBUG_WITH_TYPE("resolver",
+ llvm::dbgs() << "******** Removing coalesced away atoms:\n");
ScopedTask task(getDefaultDomain(), "removeCoalescedAwayAtoms");
_atoms.erase(std::remove_if(_atoms.begin(), _atoms.end(), [&](const Atom *a) {
return _symbolTable.isCoalescedAway(a) || _deadAtoms.count(a);
@@ -487,28 +503,53 @@ void Resolver::removeCoalescedAwayAtoms() {
}
bool Resolver::resolve() {
+ DEBUG_WITH_TYPE("resolver",
+ llvm::dbgs() << "******** Resolving atom references:\n");
updatePreloadArchiveMap();
if (!resolveUndefines())
return false;
updateReferences();
deadStripOptimize();
- if (checkUndefines())
- if (!_ctx.allowRemainingUndefines())
+ if (checkUndefines()) {
+ DEBUG_WITH_TYPE("resolver", llvm::dbgs() << "Found undefines... ");
+ if (!_ctx.allowRemainingUndefines()) {
+ DEBUG_WITH_TYPE("resolver", llvm::dbgs() << "which we don't allow\n");
return false;
+ }
+ DEBUG_WITH_TYPE("resolver", llvm::dbgs() << "which we are ok with\n");
+ }
removeCoalescedAwayAtoms();
_result->addAtoms(_atoms);
+ DEBUG_WITH_TYPE("resolver", llvm::dbgs() << "******** Finished resolver\n");
return true;
}
void Resolver::MergedFile::addAtoms(std::vector<const Atom *> &all) {
ScopedTask task(getDefaultDomain(), "addAtoms");
DEBUG_WITH_TYPE("resolver", llvm::dbgs() << "Resolver final atom list:\n");
+
for (const Atom *atom : all) {
- DEBUG_WITH_TYPE("resolver", llvm::dbgs()
- << llvm::format(" 0x%09lX", atom)
- << ", name="
- << atom->name()
- << "\n");
+#ifndef NDEBUG
+ if (auto *definedAtom = dyn_cast<DefinedAtom>(atom)) {
+ DEBUG_WITH_TYPE("resolver", llvm::dbgs()
+ << llvm::format(" 0x%09lX", atom)
+ << ", file=#"
+ << definedAtom->file().ordinal()
+ << ", atom=#"
+ << definedAtom->ordinal()
+ << ", name="
+ << definedAtom->name()
+ << ", type="
+ << definedAtom->contentType()
+ << "\n");
+ } else {
+ DEBUG_WITH_TYPE("resolver", llvm::dbgs()
+ << llvm::format(" 0x%09lX", atom)
+ << ", name="
+ << atom->name()
+ << "\n");
+ }
+#endif
addAtom(*atom);
}
}
diff --git a/lib/Core/SymbolTable.cpp b/lib/Core/SymbolTable.cpp
index f3f2da9262e0..b85a83ffbfe6 100644
--- a/lib/Core/SymbolTable.cpp
+++ b/lib/Core/SymbolTable.cpp
@@ -28,7 +28,7 @@
#include <vector>
namespace lld {
-SymbolTable::SymbolTable(LinkingContext &context) : _context(context) {}
+SymbolTable::SymbolTable(LinkingContext &context) : _ctx(context) {}
bool SymbolTable::add(const UndefinedAtom &atom) { return addByName(atom); }
@@ -185,7 +185,7 @@ bool SymbolTable::addByName(const Atom &newAtom) {
// fallthrough
}
case MCR_Error:
- if (!_context.getAllowDuplicates()) {
+ if (!_ctx.getAllowDuplicates()) {
llvm::errs() << "Duplicate symbols: "
<< existing->name()
<< ":"
@@ -207,8 +207,7 @@ bool SymbolTable::addByName(const Atom &newAtom) {
const UndefinedAtom* newUndef = cast<UndefinedAtom>(&newAtom);
bool sameCanBeNull = (existingUndef->canBeNull() == newUndef->canBeNull());
- if (!sameCanBeNull &&
- _context.warnIfCoalesableAtomsHaveDifferentCanBeNull()) {
+ if (!sameCanBeNull && _ctx.warnIfCoalesableAtomsHaveDifferentCanBeNull()) {
llvm::errs() << "lld warning: undefined symbol "
<< existingUndef->name()
<< " has different weakness in "
@@ -244,14 +243,14 @@ bool SymbolTable::addByName(const Atom &newAtom) {
(curShLib->canBeNullAtRuntime() == newShLib->canBeNullAtRuntime());
bool sameName = curShLib->loadName().equals(newShLib->loadName());
if (sameName && !sameNullness &&
- _context.warnIfCoalesableAtomsHaveDifferentCanBeNull()) {
+ _ctx.warnIfCoalesableAtomsHaveDifferentCanBeNull()) {
// FIXME: need diagonstics interface for writing warning messages
llvm::errs() << "lld warning: shared library symbol "
<< curShLib->name() << " has different weakness in "
<< curShLib->file().path() << " and in "
<< newShLib->file().path();
}
- if (!sameName && _context.warnIfCoalesableAtomsHaveDifferentLoadName()) {
+ if (!sameName && _ctx.warnIfCoalesableAtomsHaveDifferentLoadName()) {
// FIXME: need diagonstics interface for writing warning messages
llvm::errs() << "lld warning: shared library symbol "
<< curShLib->name() << " has different load path in "
@@ -268,7 +267,7 @@ bool SymbolTable::addByName(const Atom &newAtom) {
}
// Give context a chance to change which is kept.
- _context.notifySymbolTableCoalesce(existing, &newAtom, useNew);
+ _ctx.notifySymbolTableCoalesce(existing, &newAtom, useNew);
if (useNew) {
// Update name table to use new atom.
diff --git a/lib/Core/TODO.txt b/lib/Core/TODO.txt
deleted file mode 100644
index 196a3e02c2fc..000000000000
--- a/lib/Core/TODO.txt
+++ /dev/null
@@ -1,18 +0,0 @@
-lib/Core
-~~~~~~~~
-
-* Add endianness support to the native reader and writer.
-
-* The NativeReader has lots of similar code for converting arrays of ivar
- data in mapped memory into arrays of objects. The commonality can be
- factored out, maybe templatized.
-
-* The NativeFileFormat.h is old school C structs and constants. We scope
- things better by defining constants used with a struct inside the struct
- declaration.
-
-* The native reader and writer currently just blast in memory enumeration
- values (e.g. DefinedAtom::Scope) into a byte in the disk format. To support
- future changes to the enumerations, there should be a translation layer
- to map disk values to in-memory values.
-
diff --git a/lib/Core/Writer.cpp b/lib/Core/Writer.cpp
index 39bcc9e68523..93e6438a28f5 100644
--- a/lib/Core/Writer.cpp
+++ b/lib/Core/Writer.cpp
@@ -16,8 +16,4 @@ Writer::Writer() {
Writer::~Writer() {
}
-
-bool Writer::createImplicitFiles(std::vector<std::unique_ptr<File> > &) {
- return true;
-}
} // end namespace lld