1*9880d681SAndroid Build Coastguard Worker //===- Error.cpp - system_error extensions for Object -----------*- C++ -*-===// 2*9880d681SAndroid Build Coastguard Worker // 3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure 4*9880d681SAndroid Build Coastguard Worker // 5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source 6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details. 7*9880d681SAndroid Build Coastguard Worker // 8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===// 9*9880d681SAndroid Build Coastguard Worker // 10*9880d681SAndroid Build Coastguard Worker // This defines a new error_category for the Object library. 11*9880d681SAndroid Build Coastguard Worker // 12*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===// 13*9880d681SAndroid Build Coastguard Worker 14*9880d681SAndroid Build Coastguard Worker #include "llvm/Object/Error.h" 15*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/ErrorHandling.h" 16*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/ManagedStatic.h" 17*9880d681SAndroid Build Coastguard Worker 18*9880d681SAndroid Build Coastguard Worker using namespace llvm; 19*9880d681SAndroid Build Coastguard Worker using namespace object; 20*9880d681SAndroid Build Coastguard Worker 21*9880d681SAndroid Build Coastguard Worker namespace { 22*9880d681SAndroid Build Coastguard Worker // FIXME: This class is only here to support the transition to llvm::Error. It 23*9880d681SAndroid Build Coastguard Worker // will be removed once this transition is complete. Clients should prefer to 24*9880d681SAndroid Build Coastguard Worker // deal with the Error value directly, rather than converting to error_code. 25*9880d681SAndroid Build Coastguard Worker class _object_error_category : public std::error_category { 26*9880d681SAndroid Build Coastguard Worker public: 27*9880d681SAndroid Build Coastguard Worker const char* name() const LLVM_NOEXCEPT override; 28*9880d681SAndroid Build Coastguard Worker std::string message(int ev) const override; 29*9880d681SAndroid Build Coastguard Worker }; 30*9880d681SAndroid Build Coastguard Worker } 31*9880d681SAndroid Build Coastguard Worker name() const32*9880d681SAndroid Build Coastguard Workerconst char *_object_error_category::name() const LLVM_NOEXCEPT { 33*9880d681SAndroid Build Coastguard Worker return "llvm.object"; 34*9880d681SAndroid Build Coastguard Worker } 35*9880d681SAndroid Build Coastguard Worker message(int EV) const36*9880d681SAndroid Build Coastguard Workerstd::string _object_error_category::message(int EV) const { 37*9880d681SAndroid Build Coastguard Worker object_error E = static_cast<object_error>(EV); 38*9880d681SAndroid Build Coastguard Worker switch (E) { 39*9880d681SAndroid Build Coastguard Worker case object_error::arch_not_found: 40*9880d681SAndroid Build Coastguard Worker return "No object file for requested architecture"; 41*9880d681SAndroid Build Coastguard Worker case object_error::invalid_file_type: 42*9880d681SAndroid Build Coastguard Worker return "The file was not recognized as a valid object file"; 43*9880d681SAndroid Build Coastguard Worker case object_error::parse_failed: 44*9880d681SAndroid Build Coastguard Worker return "Invalid data was encountered while parsing the file"; 45*9880d681SAndroid Build Coastguard Worker case object_error::unexpected_eof: 46*9880d681SAndroid Build Coastguard Worker return "The end of the file was unexpectedly encountered"; 47*9880d681SAndroid Build Coastguard Worker case object_error::string_table_non_null_end: 48*9880d681SAndroid Build Coastguard Worker return "String table must end with a null terminator"; 49*9880d681SAndroid Build Coastguard Worker case object_error::invalid_section_index: 50*9880d681SAndroid Build Coastguard Worker return "Invalid section index"; 51*9880d681SAndroid Build Coastguard Worker case object_error::bitcode_section_not_found: 52*9880d681SAndroid Build Coastguard Worker return "Bitcode section not found in object file"; 53*9880d681SAndroid Build Coastguard Worker } 54*9880d681SAndroid Build Coastguard Worker llvm_unreachable("An enumerator of object_error does not have a message " 55*9880d681SAndroid Build Coastguard Worker "defined."); 56*9880d681SAndroid Build Coastguard Worker } 57*9880d681SAndroid Build Coastguard Worker 58*9880d681SAndroid Build Coastguard Worker char BinaryError::ID = 0; 59*9880d681SAndroid Build Coastguard Worker char GenericBinaryError::ID = 0; 60*9880d681SAndroid Build Coastguard Worker GenericBinaryError(Twine Msg)61*9880d681SAndroid Build Coastguard WorkerGenericBinaryError::GenericBinaryError(Twine Msg) : Msg(Msg.str()) {} 62*9880d681SAndroid Build Coastguard Worker GenericBinaryError(Twine Msg,object_error ECOverride)63*9880d681SAndroid Build Coastguard WorkerGenericBinaryError::GenericBinaryError(Twine Msg, object_error ECOverride) 64*9880d681SAndroid Build Coastguard Worker : Msg(Msg.str()) { 65*9880d681SAndroid Build Coastguard Worker setErrorCode(make_error_code(ECOverride)); 66*9880d681SAndroid Build Coastguard Worker } 67*9880d681SAndroid Build Coastguard Worker log(raw_ostream & OS) const68*9880d681SAndroid Build Coastguard Workervoid GenericBinaryError::log(raw_ostream &OS) const { 69*9880d681SAndroid Build Coastguard Worker OS << Msg; 70*9880d681SAndroid Build Coastguard Worker } 71*9880d681SAndroid Build Coastguard Worker 72*9880d681SAndroid Build Coastguard Worker static ManagedStatic<_object_error_category> error_category; 73*9880d681SAndroid Build Coastguard Worker object_category()74*9880d681SAndroid Build Coastguard Workerconst std::error_category &object::object_category() { 75*9880d681SAndroid Build Coastguard Worker return *error_category; 76*9880d681SAndroid Build Coastguard Worker } 77*9880d681SAndroid Build Coastguard Worker isNotObjectErrorInvalidFileType(llvm::Error Err)78*9880d681SAndroid Build Coastguard Workerllvm::Error llvm::object::isNotObjectErrorInvalidFileType(llvm::Error Err) { 79*9880d681SAndroid Build Coastguard Worker if (auto Err2 = 80*9880d681SAndroid Build Coastguard Worker handleErrors(std::move(Err), 81*9880d681SAndroid Build Coastguard Worker [](std::unique_ptr<ECError> M) { 82*9880d681SAndroid Build Coastguard Worker // Try to handle 'M'. If successful, return a success value from 83*9880d681SAndroid Build Coastguard Worker // the handler. 84*9880d681SAndroid Build Coastguard Worker if (M->convertToErrorCode() == object_error::invalid_file_type) 85*9880d681SAndroid Build Coastguard Worker return Error::success(); 86*9880d681SAndroid Build Coastguard Worker 87*9880d681SAndroid Build Coastguard Worker // We failed to handle 'M' - return it from the handler. 88*9880d681SAndroid Build Coastguard Worker // This value will be passed back from catchErrors and 89*9880d681SAndroid Build Coastguard Worker // wind up in Err2, where it will be returned from this function. 90*9880d681SAndroid Build Coastguard Worker return Error(std::move(M)); 91*9880d681SAndroid Build Coastguard Worker })) 92*9880d681SAndroid Build Coastguard Worker return Err2; 93*9880d681SAndroid Build Coastguard Worker return Err; 94*9880d681SAndroid Build Coastguard Worker } 95