diff options
Diffstat (limited to 'lib/Core')
| -rw-r--r-- | lib/Core/DefinedAtom.cpp | 1 | ||||
| -rw-r--r-- | lib/Core/Error.cpp | 52 | ||||
| -rw-r--r-- | lib/Core/File.cpp | 8 | ||||
| -rw-r--r-- | lib/Core/LinkingContext.cpp | 8 | ||||
| -rw-r--r-- | lib/Core/Makefile | 13 | ||||
| -rw-r--r-- | lib/Core/Reader.cpp | 16 | ||||
| -rw-r--r-- | lib/Core/Resolver.cpp | 57 | ||||
| -rw-r--r-- | lib/Core/SymbolTable.cpp | 13 | ||||
| -rw-r--r-- | lib/Core/TODO.txt | 18 | ||||
| -rw-r--r-- | lib/Core/Writer.cpp | 4 |
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 |
