#ifndef LLD_CORE_ERROR_H
#define LLD_CORE_ERROR_H
+#include "lld/Core/LLVM.h"
#include "llvm/Support/system_error.h"
namespace lld {
return llvm::error_code(static_cast<int>(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 {
#include "lld/Core/Error.h"
+#include "llvm/ADT/Twine.h"
#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/Mutex.h"
+
+#include <string>
+#include <vector>
using namespace lld;
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<true> 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<std::string> _messages;
+ llvm::sys::SmartMutex<true> _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);
+}
+
+}
+
#include "File.h"
#include "Atoms.h"
+#include "lld/Core/Error.h"
#include "lld/Core/LLVM.h"
#include "llvm/Support/MachO.h"
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<uint8_t> byteContent = section.content.slice(offset, 4);
file.addDefinedAtom(StringRef(), DefinedAtom::scopeLinkageUnit,
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<uint8_t> byteContent = section.content.slice(offset, 8);
file.addDefinedAtom(StringRef(), DefinedAtom::scopeLinkageUnit,
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<uint8_t> byteContent = section.content.slice(offset, 16);
file.addDefinedAtom(StringRef(), DefinedAtom::scopeLinkageUnit,