Index: COFF/Chunks.cpp =================================================================== --- COFF/Chunks.cpp +++ COFF/Chunks.cpp @@ -10,7 +10,6 @@ #include "Chunks.h" #include "InputFiles.h" #include "Writer.h" -#include "lld/Core/Error.h" #include "llvm/ADT/STLExtras.h" #include "llvm/Object/COFF.h" #include "llvm/Support/COFF.h" Index: COFF/Driver.cpp =================================================================== --- COFF/Driver.cpp +++ COFF/Driver.cpp @@ -13,7 +13,6 @@ #include "Memory.h" #include "SymbolTable.h" #include "Writer.h" -#include "lld/Core/Error.h" #include "llvm/ADT/Optional.h" #include "llvm/ADT/STLExtras.h" #include "llvm/Option/Arg.h" Index: COFF/DriverUtils.cpp =================================================================== --- COFF/DriverUtils.cpp +++ COFF/DriverUtils.cpp @@ -14,8 +14,8 @@ //===----------------------------------------------------------------------===// #include "Driver.h" +#include "Error.h" #include "Memory.h" -#include "lld/Core/Error.h" #include "llvm/ADT/Optional.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringSwitch.h" @@ -24,7 +24,6 @@ #include "llvm/Option/ArgList.h" #include "llvm/Option/Option.h" #include "llvm/Support/CommandLine.h" -#include "llvm/Support/Format.h" #include "llvm/Support/Path.h" #include "llvm/Support/Process.h" #include "llvm/Support/raw_ostream.h" @@ -114,8 +113,10 @@ .Case("x64", IMAGE_FILE_MACHINE_AMD64) .Case("x86", IMAGE_FILE_MACHINE_I386) .Default(IMAGE_FILE_MACHINE_UNKNOWN); - if (MT == IMAGE_FILE_MACHINE_UNKNOWN) - return make_dynamic_error_code("unknown /machine argument" + S); + if (MT == IMAGE_FILE_MACHINE_UNKNOWN) { + llvm::errs() << "unknown /machine argument" << S << "\n"; + return make_error_code(DriverError::InvalidOption); + } return MT; } // If /machine option is missing, we need to take a look at @@ -132,10 +133,14 @@ std::error_code parseNumbers(StringRef Arg, uint64_t *Addr, uint64_t *Size) { StringRef S1, S2; std::tie(S1, S2) = Arg.split(','); - if (S1.getAsInteger(0, *Addr)) - return make_dynamic_error_code(Twine("invalid number: ") + S1); - if (Size && !S2.empty() && S2.getAsInteger(0, *Size)) - return make_dynamic_error_code(Twine("invalid number: ") + S2); + if (S1.getAsInteger(0, *Addr)) { + llvm::errs() << "invalid number: " << S1 << "\n"; + return make_error_code(DriverError::InvalidOption); + } + if (Size && !S2.empty() && S2.getAsInteger(0, *Size)) { + llvm::errs() << "invalid number: " << S2 << "\n"; + return make_error_code(DriverError::InvalidOption); + } return std::error_code(); } @@ -144,11 +149,15 @@ std::error_code parseVersion(StringRef Arg, uint32_t *Major, uint32_t *Minor) { StringRef S1, S2; std::tie(S1, S2) = Arg.split('.'); - if (S1.getAsInteger(0, *Major)) - return make_dynamic_error_code(Twine("invalid number: ") + S1); + if (S1.getAsInteger(0, *Major)) { + llvm::errs() << "invalid number: " << S1 << "\n"; + return make_error_code(DriverError::InvalidOption); + } *Minor = 0; - if (!S2.empty() && S2.getAsInteger(0, *Minor)) - return make_dynamic_error_code(Twine("invalid number: ") + S2); + if (!S2.empty() && S2.getAsInteger(0, *Minor)) { + llvm::errs() << "invalid number: " << S2 << "\n"; + return make_error_code(DriverError::InvalidOption); + } return std::error_code(); } @@ -168,8 +177,10 @@ .Case("posix", IMAGE_SUBSYSTEM_POSIX_CUI) .Case("windows", IMAGE_SUBSYSTEM_WINDOWS_GUI) .Default(IMAGE_SUBSYSTEM_UNKNOWN); - if (*Sys == IMAGE_SUBSYSTEM_UNKNOWN) - return make_dynamic_error_code(Twine("unknown subsystem: ") + SysStr); + if (*Sys == IMAGE_SUBSYSTEM_UNKNOWN) { + llvm::errs() << "unknown subsystem: " << SysStr << "\n"; + return make_error_code(DriverError::InvalidOption); + } if (!Ver.empty()) if (auto EC = parseVersion(Ver, Major, Minor)) return EC; @@ -207,13 +218,11 @@ std::unique_ptr Args( Table.ParseArgs(&Argv[1], &Argv[Argc], MissingIndex, MissingCount)); if (MissingCount) { - std::string S; - llvm::raw_string_ostream OS(S); - OS << llvm::format("missing arg value for \"%s\", expected %d argument%s.", - Args->getArgString(MissingIndex), MissingCount, - (MissingCount == 1 ? "" : "s")); - OS.flush(); - return make_dynamic_error_code(StringRef(S)); + llvm::errs() << "missing arg value for \"" + << Args->getArgString(MissingIndex) + << "\", expected " << MissingCount + << (MissingCount == 1 ? " argument.\n" : " arguments.\n"); + return make_error_code(DriverError::InvalidOption); } for (auto *Arg : Args->filtered(OPT_UNKNOWN)) llvm::errs() << "ignoring unknown argument: " << Arg->getSpelling() << "\n"; Index: COFF/Error.h =================================================================== --- /dev/null +++ COFF/Error.h @@ -0,0 +1,94 @@ +//===- Error.h ------------------------------------------------------------===// +// +// The LLVM Linker +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLD_COFF_ERROR_H +#define LLD_COFF_ERROR_H + +#include +#include +#include "llvm/Support/ErrorHandling.h" + +namespace lld { +namespace coff { + +// Driver errors +enum class DriverError { Success, InvalidOption }; + +class DriverErrorCategory : public std::error_category { +public: + const char *name() const override { return "lld.driver"; } + + std::string message(int EV) const override { + switch (static_cast(EV)) { + case DriverError::Success: + return "Success"; + case DriverError::InvalidOption: + return "Invalid option"; + } + llvm_unreachable("unknown error"); + } +}; + +inline std::error_code make_error_code(DriverError Err) { + static DriverErrorCategory C; + return std::error_code(static_cast(Err), C); +} + +// InputFile errors +enum class ReaderError { Success, InvalidFile, BrokenFile }; + +class ReaderErrorCategory : public std::error_category { +public: + const char *name() const override { return "lld.reader"; } + + std::string message(int EV) const override { + switch (static_cast(EV)) { + case ReaderError::Success: + return "Success"; + case ReaderError::InvalidFile: + return "Invalid file"; + case ReaderError::BrokenFile: + return "broken file"; + } + llvm_unreachable("unknown error"); + } +}; + +inline std::error_code make_error_code(ReaderError Err) { + static ReaderErrorCategory C; + return std::error_code(static_cast(Err), C); +} + +// SymbolTable errors +enum class SymbolError { Success, Duplicate }; + +class SymbolErrorCategory : public std::error_category { +public: + const char *name() const override { return "lld.symbol"; } + + std::string message(int EV) const override { + switch (static_cast(EV)) { + case SymbolError::Success: + return "Success"; + case SymbolError::Duplicate: + return "Duplicate symbols"; + } + llvm_unreachable("unknown error"); + } +}; + +inline std::error_code make_error_code(SymbolError Err) { + static SymbolErrorCategory C; + return std::error_code(static_cast(Err), C); +} + +} // namespace coff +} // namespace lld + +#endif Index: COFF/InputFiles.cpp =================================================================== --- COFF/InputFiles.cpp +++ COFF/InputFiles.cpp @@ -8,9 +8,9 @@ //===----------------------------------------------------------------------===// #include "Chunks.h" +#include "Error.h" #include "InputFiles.h" #include "Writer.h" -#include "lld/Core/Error.h" #include "llvm/ADT/STLExtras.h" #include "llvm/Object/COFF.h" #include "llvm/Support/COFF.h" @@ -108,7 +108,8 @@ Bin.release(); COFFObj.reset(Obj); } else { - return make_dynamic_error_code(Twine(Filename) + " is not a COFF file."); + llvm::errs() << Filename << " is not a COFF file.\n"; + return make_error_code(ReaderError::InvalidFile); } // Read section and symbol tables. @@ -128,12 +129,16 @@ for (uint32_t I = 1; I < NumSections + 1; ++I) { const coff_section *Sec; StringRef Name; - if (auto EC = COFFObj->getSection(I, Sec)) - return make_dynamic_error_code(Twine("getSection failed: ") + Name + - ": " + EC.message()); - if (auto EC = COFFObj->getSectionName(Sec, Name)) - return make_dynamic_error_code(Twine("getSectionName failed: ") + Name + - ": " + EC.message()); + if (auto EC = COFFObj->getSection(I, Sec)) { + llvm::errs() << "getSection failed: " << Name << ": " + << EC.message() << "\n"; + return make_error_code(ReaderError::BrokenFile); + } + if (auto EC = COFFObj->getSectionName(Sec, Name)) { + llvm::errs() << "getSectionName failed: " << Name << ": " + << EC.message() << "\n"; + return make_error_code(ReaderError::BrokenFile); + } if (Name == ".drectve") { ArrayRef Data; COFFObj->getSectionContents(Sec, Data); @@ -159,16 +164,20 @@ for (uint32_t I = 0; I < NumSymbols; ++I) { // Get a COFFSymbolRef object. auto SymOrErr = COFFObj->getSymbol(I); - if (auto EC = SymOrErr.getError()) - return make_dynamic_error_code(Twine("broken object file: ") + Filename + - ": " + EC.message()); + if (auto EC = SymOrErr.getError()) { + llvm::dbgs() << "broken object file: " << Filename << ": " + << EC.message() << "\n"; + return make_error_code(ReaderError::BrokenFile); + } COFFSymbolRef Sym = SymOrErr.get(); // Get a symbol name. StringRef SymbolName; - if (auto EC = COFFObj->getSymbolName(Sym, SymbolName)) - return make_dynamic_error_code(Twine("broken object file: ") + Filename + - ": " + EC.message()); + if (auto EC = COFFObj->getSymbolName(Sym, SymbolName)) { + llvm::dbgs() << "broken object file: " << Filename << ": " + << EC.message() << "\n"; + return make_error_code(ReaderError::BrokenFile); + } // Skip special symbols. if (SymbolName == "@comp.id" || SymbolName == "@feat.00") continue; @@ -225,8 +234,10 @@ const auto *Hdr = reinterpret_cast(Buf); // Check if the total size is valid. - if (End - Buf != sizeof(*Hdr) + Hdr->SizeOfData) - return make_dynamic_error_code("broken import library"); + if (End - Buf != sizeof(*Hdr) + Hdr->SizeOfData) { + llvm::errs() << "broken import library\n"; + return make_error_code(ReaderError::BrokenFile); + } // Read names and create an __imp_ symbol. StringRef Name = StringAlloc.save(StringRef(Buf + sizeof(*Hdr))); Index: COFF/SymbolTable.cpp =================================================================== --- COFF/SymbolTable.cpp +++ COFF/SymbolTable.cpp @@ -9,8 +9,8 @@ #include "Config.h" #include "Driver.h" +#include "Error.h" #include "SymbolTable.h" -#include "lld/Core/Error.h" #include "llvm/ADT/STLExtras.h" #include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" @@ -117,8 +117,10 @@ int comp = Existing->compare(New); if (comp < 0) Sym->Body = New; - if (comp == 0) - return make_dynamic_error_code(Twine("duplicate symbol: ") + Name); + if (comp == 0) { + llvm::dbgs() << "duplicate symbol: " << Name << "\n"; + return make_error_code(SymbolError::Duplicate); + } // If we have an Undefined symbol for a Lazy symbol, we need // to read an archive member to replace the Lazy symbol with Index: COFF/Symbols.cpp =================================================================== --- COFF/Symbols.cpp +++ COFF/Symbols.cpp @@ -7,9 +7,9 @@ // //===----------------------------------------------------------------------===// +#include "Error.h" #include "InputFiles.h" #include "Symbols.h" -#include "lld/Core/Error.h" #include "llvm/ADT/STLExtras.h" #include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" @@ -84,8 +84,10 @@ if (Magic == file_magic::coff_import_library) return std::unique_ptr(new ImportFile(MBRef)); - if (Magic != file_magic::coff_object) - return make_dynamic_error_code("unknown file type"); + if (Magic != file_magic::coff_object) { + llvm::dbgs() << File->getName() << ": unknown file type\n"; + return make_error_code(ReaderError::InvalidFile); + } std::unique_ptr Obj(new ObjectFile(MBRef.getBufferIdentifier(), MBRef)); Obj->setParentName(File->getName()); Index: COFF/Writer.cpp =================================================================== --- COFF/Writer.cpp +++ COFF/Writer.cpp @@ -9,7 +9,6 @@ #include "Config.h" #include "Writer.h" -#include "lld/Core/Error.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/ADT/STLExtras.h" @@ -300,9 +299,10 @@ std::error_code Writer::openFile(StringRef Path) { if (auto EC = FileOutputBuffer::create(Path, FileSize, Buffer, - FileOutputBuffer::F_executable)) - return make_dynamic_error_code(Twine("Failed to open ") + Path + ": " + - EC.message()); + FileOutputBuffer::F_executable)) { + llvm::errs() << "failed to open " << Path << ": " << EC.message() << "\n"; + return EC; + } return std::error_code(); }