From: Nick Kledzik Date: Tue, 27 May 2014 19:35:41 +0000 (+0000) Subject: Add make_dynamic_error_code(). X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=181ce5ee037c0ec227708d083b92202960d5ad69;p=platform%2Fupstream%2Fllvm.git Add make_dynamic_error_code(). This is a short-term fix to allow lld Readers to return error messages with dynamic content. The long term fix will be to enhance ErrorOr<> to work with errors other than error_code. Or to change the interface to Readers to pass down a diagnostics object through which all error messages are written. llvm-svn: 209681 --- diff --git a/lld/include/lld/Core/Error.h b/lld/include/lld/Core/Error.h index a91ed30..d59520a 100644 --- a/lld/include/lld/Core/Error.h +++ b/lld/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,16 @@ inline llvm::error_code make_error_code(ReaderError e) { 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. +/// Note: Once ErrorOr<> is updated to work with errors other than error_code, +/// this can be updated to return some other kind of error. +llvm::error_code make_dynamic_error_code(StringRef msg); +llvm::error_code make_dynamic_error_code(const Twine &msg); + } // end namespace lld namespace llvm { diff --git a/lld/lib/Core/Error.cpp b/lld/lib/Core/Error.cpp index 32496b9..d8b6560 100644 --- a/lld/lib/Core/Error.cpp +++ b/lld/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,52 @@ const llvm::error_category &lld::ReaderErrorCategory() { static _ReaderErrorCategory i; return i; } + + + + +namespace lld { + + +/// Temporary class to enable make_dynamic_error_code() until +/// llvm::ErrorOr<> is updated to work with error encapsulations +/// other than error_code. +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); +} + +} + diff --git a/lld/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp b/lld/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp index 769cb39..596a8fe 100644 --- a/lld/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp +++ b/lld/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 @@ static error_code processSection(MachOFile &file, const Section §ion, 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 @@ static error_code processSection(MachOFile &file, const Section §ion, 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 @@ static error_code processSection(MachOFile &file, const Section §ion, 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,