117a519f9SDimitry Andric //===- Error.cpp - system_error extensions for Object -----------*- C++ -*-===// 217a519f9SDimitry Andric // 317a519f9SDimitry Andric // The LLVM Compiler Infrastructure 417a519f9SDimitry Andric // 517a519f9SDimitry Andric // This file is distributed under the University of Illinois Open Source 617a519f9SDimitry Andric // License. See LICENSE.TXT for details. 717a519f9SDimitry Andric // 817a519f9SDimitry Andric //===----------------------------------------------------------------------===// 917a519f9SDimitry Andric // 1017a519f9SDimitry Andric // This defines a new error_category for the Object library. 1117a519f9SDimitry Andric // 1217a519f9SDimitry Andric //===----------------------------------------------------------------------===// 1317a519f9SDimitry Andric 1417a519f9SDimitry Andric #include "llvm/Object/Error.h" 1517a519f9SDimitry Andric #include "llvm/Support/ErrorHandling.h" 1639d628a0SDimitry Andric #include "llvm/Support/ManagedStatic.h" 1717a519f9SDimitry Andric 1817a519f9SDimitry Andric using namespace llvm; 1917a519f9SDimitry Andric using namespace object; 2017a519f9SDimitry Andric 2117a519f9SDimitry Andric namespace { 223ca95b02SDimitry Andric // FIXME: This class is only here to support the transition to llvm::Error. It 233ca95b02SDimitry Andric // will be removed once this transition is complete. Clients should prefer to 243ca95b02SDimitry Andric // deal with the Error value directly, rather than converting to error_code. 2591bc56edSDimitry Andric class _object_error_category : public std::error_category { 2617a519f9SDimitry Andric public: 27d88c1a5aSDimitry Andric const char* name() const noexcept override; 2891bc56edSDimitry Andric std::string message(int ev) const override; 2917a519f9SDimitry Andric }; 3017a519f9SDimitry Andric } 3117a519f9SDimitry Andric name() const32d88c1a5aSDimitry Andricconst char *_object_error_category::name() const noexcept { 3317a519f9SDimitry Andric return "llvm.object"; 3417a519f9SDimitry Andric } 3517a519f9SDimitry Andric message(int EV) const3691bc56edSDimitry Andricstd::string _object_error_category::message(int EV) const { 3791bc56edSDimitry Andric object_error E = static_cast<object_error>(EV); 38f785676fSDimitry Andric switch (E) { 39f785676fSDimitry Andric case object_error::arch_not_found: 40f785676fSDimitry Andric return "No object file for requested architecture"; 4117a519f9SDimitry Andric case object_error::invalid_file_type: 4217a519f9SDimitry Andric return "The file was not recognized as a valid object file"; 4317a519f9SDimitry Andric case object_error::parse_failed: 4417a519f9SDimitry Andric return "Invalid data was encountered while parsing the file"; 4517a519f9SDimitry Andric case object_error::unexpected_eof: 4617a519f9SDimitry Andric return "The end of the file was unexpectedly encountered"; 473dac3a9bSDimitry Andric case object_error::string_table_non_null_end: 483dac3a9bSDimitry Andric return "String table must end with a null terminator"; 493dac3a9bSDimitry Andric case object_error::invalid_section_index: 503dac3a9bSDimitry Andric return "Invalid section index"; 5139d628a0SDimitry Andric case object_error::bitcode_section_not_found: 5239d628a0SDimitry Andric return "Bitcode section not found in object file"; 53d88c1a5aSDimitry Andric case object_error::invalid_symbol_index: 54d88c1a5aSDimitry Andric return "Invalid symbol index"; 55f785676fSDimitry Andric } 5617a519f9SDimitry Andric llvm_unreachable("An enumerator of object_error does not have a message " 5717a519f9SDimitry Andric "defined."); 5817a519f9SDimitry Andric } 5917a519f9SDimitry Andric anchor()60*b5893f02SDimitry Andricvoid BinaryError::anchor() {} 613ca95b02SDimitry Andric char BinaryError::ID = 0; 623ca95b02SDimitry Andric char GenericBinaryError::ID = 0; 633ca95b02SDimitry Andric GenericBinaryError(Twine Msg)643ca95b02SDimitry AndricGenericBinaryError::GenericBinaryError(Twine Msg) : Msg(Msg.str()) {} 653ca95b02SDimitry Andric GenericBinaryError(Twine Msg,object_error ECOverride)663ca95b02SDimitry AndricGenericBinaryError::GenericBinaryError(Twine Msg, object_error ECOverride) 673ca95b02SDimitry Andric : Msg(Msg.str()) { 683ca95b02SDimitry Andric setErrorCode(make_error_code(ECOverride)); 693ca95b02SDimitry Andric } 703ca95b02SDimitry Andric log(raw_ostream & OS) const713ca95b02SDimitry Andricvoid GenericBinaryError::log(raw_ostream &OS) const { 723ca95b02SDimitry Andric OS << Msg; 733ca95b02SDimitry Andric } 743ca95b02SDimitry Andric 7539d628a0SDimitry Andric static ManagedStatic<_object_error_category> error_category; 7639d628a0SDimitry Andric object_category()7791bc56edSDimitry Andricconst std::error_category &object::object_category() { 7839d628a0SDimitry Andric return *error_category; 7917a519f9SDimitry Andric } 803ca95b02SDimitry Andric isNotObjectErrorInvalidFileType(llvm::Error Err)813ca95b02SDimitry Andricllvm::Error llvm::object::isNotObjectErrorInvalidFileType(llvm::Error Err) { 823ca95b02SDimitry Andric if (auto Err2 = 83d88c1a5aSDimitry Andric handleErrors(std::move(Err), [](std::unique_ptr<ECError> M) -> Error { 843ca95b02SDimitry Andric // Try to handle 'M'. If successful, return a success value from 853ca95b02SDimitry Andric // the handler. 863ca95b02SDimitry Andric if (M->convertToErrorCode() == object_error::invalid_file_type) 873ca95b02SDimitry Andric return Error::success(); 883ca95b02SDimitry Andric 893ca95b02SDimitry Andric // We failed to handle 'M' - return it from the handler. 903ca95b02SDimitry Andric // This value will be passed back from catchErrors and 913ca95b02SDimitry Andric // wind up in Err2, where it will be returned from this function. 923ca95b02SDimitry Andric return Error(std::move(M)); 933ca95b02SDimitry Andric })) 943ca95b02SDimitry Andric return Err2; 953ca95b02SDimitry Andric return Err; 963ca95b02SDimitry Andric } 97