Index: include/lld/Core/Error.h =================================================================== --- include/lld/Core/Error.h +++ include/lld/Core/Error.h @@ -14,6 +14,7 @@ #ifndef LLD_CORE_ERROR_H #define LLD_CORE_ERROR_H +#include "lld/Core/LLVM.h" #include "llvm/Support/system_error.h" namespace lld { @@ -82,6 +83,14 @@ return llvm::error_code(static_cast(e), ReaderErrorCategory()); } + +/// Creates an error_code object that has associated with it an arbitrary +/// error messsage. The value() of the error_code will always be non-zero +/// but its value is meaningless. The messsage() will be (a copy of) the +/// supplied error string. +llvm::error_code make_dynamic_error_code(StringRef msg); +llvm::error_code make_dynamic_error_code(const Twine &msg); + } // end namespace lld namespace llvm { Index: lib/Core/Error.cpp =================================================================== --- lib/Core/Error.cpp +++ lib/Core/Error.cpp @@ -9,7 +9,12 @@ #include "lld/Core/Error.h" +#include "llvm/ADT/Twine.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/Mutex.h" + +#include +#include using namespace lld; @@ -153,3 +158,48 @@ static _ReaderErrorCategory i; return i; } + + + + +namespace lld { + +class dynamic_error_category : public llvm::_do_message { +public: + const char *name() const override { return "lld.dynamic_error"; } + + std::string message(int ev) const override { + assert(ev >= 0); + assert(ev < (int)_messages.size()); + // The value is an index into the string vector. + return _messages[ev]; + } + + int add(std::string msg) { + llvm::sys::SmartScopedLock lock(_mutex); + // Value zero is always the successs value. + if (_messages.empty()) + _messages.push_back("Success"); + _messages.push_back(msg); + // Return the index of the string just appended. + return _messages.size() - 1; + } + +private: + std::vector _messages; + llvm::sys::SmartMutex _mutex; +}; + +static dynamic_error_category categorySingleton; + + +llvm::error_code make_dynamic_error_code(StringRef msg) { + return llvm::error_code(categorySingleton.add(msg), categorySingleton); +} + +llvm::error_code make_dynamic_error_code(const Twine &msg) { + return llvm::error_code(categorySingleton.add(msg.str()), categorySingleton); +} + +} + Index: lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp =================================================================== --- lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp +++ lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp @@ -24,6 +24,7 @@ #include "File.h" #include "Atoms.h" +#include "lld/Core/Error.h" #include "lld/Core/LLVM.h" #include "llvm/Support/MachO.h" @@ -129,7 +130,11 @@ break; case llvm::MachO::S_4BYTE_LITERALS: if ((section.content.size() % 4) != 0) - return llvm::make_error_code(llvm::errc::executable_format_error); + return make_dynamic_error_code(Twine("Section ") + section.segmentName + + "/" + section.sectionName + + " has type S_4BYTE_LITERALS but its " + "size (" + Twine(section.content.size()) + + ") is not a multiple of 4"); for (size_t i = 0, e = section.content.size(); i != e; i += 4) { ArrayRef byteContent = section.content.slice(offset, 4); file.addDefinedAtom(StringRef(), DefinedAtom::scopeLinkageUnit, @@ -139,7 +144,11 @@ break; case llvm::MachO::S_8BYTE_LITERALS: if ((section.content.size() % 8) != 0) - return llvm::make_error_code(llvm::errc::executable_format_error); + return make_dynamic_error_code(Twine("Section ") + section.segmentName + + "/" + section.sectionName + + " has type S_8YTE_LITERALS but its " + "size (" + Twine(section.content.size()) + + ") is not a multiple of 8"); for (size_t i = 0, e = section.content.size(); i != e; i += 8) { ArrayRef byteContent = section.content.slice(offset, 8); file.addDefinedAtom(StringRef(), DefinedAtom::scopeLinkageUnit, @@ -149,7 +158,11 @@ break; case llvm::MachO::S_16BYTE_LITERALS: if ((section.content.size() % 16) != 0) - return llvm::make_error_code(llvm::errc::executable_format_error); + return make_dynamic_error_code(Twine("Section ") + section.segmentName + + "/" + section.sectionName + + " has type S_16BYTE_LITERALS but its " + "size (" + Twine(section.content.size()) + + ") is not a multiple of 16"); for (size_t i = 0, e = section.content.size(); i != e; i += 16) { ArrayRef byteContent = section.content.slice(offset, 16); file.addDefinedAtom(StringRef(), DefinedAtom::scopeLinkageUnit,