[lld] r238714 - COFF: Define an error category for the linker.

Rui Ueyama ruiu at google.com
Sun May 31 19:58:16 PDT 2015


Author: ruiu
Date: Sun May 31 21:58:15 2015
New Revision: 238714

URL: http://llvm.org/viewvc/llvm-project?rev=238714&view=rev
Log:
COFF: Define an error category for the linker.

Instead of returning non-categorized errors, return categorized errors.
All uses of make_dynamic_error_code are removed.

Because we don't have error reporting mechanism, I just chose to print out
error messages to stderr, and then return an error object. Not sure if
that's the right thing to do, but at least it seems practical.

http://reviews.llvm.org/D10129

Added:
    lld/trunk/COFF/Error.h
Modified:
    lld/trunk/COFF/Chunks.cpp
    lld/trunk/COFF/Driver.cpp
    lld/trunk/COFF/DriverUtils.cpp
    lld/trunk/COFF/InputFiles.cpp
    lld/trunk/COFF/SymbolTable.cpp
    lld/trunk/COFF/Symbols.cpp
    lld/trunk/COFF/Writer.cpp

Modified: lld/trunk/COFF/Chunks.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Chunks.cpp?rev=238714&r1=238713&r2=238714&view=diff
==============================================================================
--- lld/trunk/COFF/Chunks.cpp (original)
+++ lld/trunk/COFF/Chunks.cpp Sun May 31 21:58:15 2015
@@ -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"

Modified: lld/trunk/COFF/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Driver.cpp?rev=238714&r1=238713&r2=238714&view=diff
==============================================================================
--- lld/trunk/COFF/Driver.cpp (original)
+++ lld/trunk/COFF/Driver.cpp Sun May 31 21:58:15 2015
@@ -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/ADT/StringSwitch.h"

Modified: lld/trunk/COFF/DriverUtils.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/DriverUtils.cpp?rev=238714&r1=238713&r2=238714&view=diff
==============================================================================
--- lld/trunk/COFF/DriverUtils.cpp (original)
+++ lld/trunk/COFF/DriverUtils.cpp Sun May 31 21:58:15 2015
@@ -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"
@@ -46,8 +45,10 @@ ErrorOr<MachineTypes> getMachineType(llv
                           .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(LLDError::InvalidOption);
+    }
     return MT;
   }
   return IMAGE_FILE_MACHINE_UNKNOWN;
@@ -57,10 +58,14 @@ ErrorOr<MachineTypes> getMachineType(llv
 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(LLDError::InvalidOption);
+  }
+  if (Size && !S2.empty() && S2.getAsInteger(0, *Size)) {
+    llvm::errs() << "invalid number: " << S2 << "\n";
+    return make_error_code(LLDError::InvalidOption);
+  }
   return std::error_code();
 }
 
@@ -69,11 +74,15 @@ std::error_code parseNumbers(StringRef A
 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(LLDError::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(LLDError::InvalidOption);
+  }
   return std::error_code();
 }
 
@@ -93,8 +102,10 @@ std::error_code parseSubsystem(StringRef
     .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(LLDError::InvalidOption);
+  }
   if (!Ver.empty())
     if (auto EC = parseVersion(Ver, Major, Minor))
       return EC;
@@ -132,13 +143,11 @@ parseArgs(int Argc, const char *Argv[])
   std::unique_ptr<llvm::opt::InputArgList> 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(LLDError::InvalidOption);
   }
   for (auto *Arg : Args->filtered(OPT_UNKNOWN))
     llvm::errs() << "ignoring unknown argument: " << Arg->getSpelling() << "\n";

Added: lld/trunk/COFF/Error.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Error.h?rev=238714&view=auto
==============================================================================
--- lld/trunk/COFF/Error.h (added)
+++ lld/trunk/COFF/Error.h Sun May 31 21:58:15 2015
@@ -0,0 +1,54 @@
+//===- 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 <string>
+#include <system_error>
+#include "llvm/Support/ErrorHandling.h"
+
+namespace lld {
+namespace coff {
+
+enum class LLDError {
+  InvalidOption = 1,
+  InvalidFile,
+  BrokenFile,
+  DuplicateSymbols,
+};
+
+class LLDErrorCategory : public std::error_category {
+public:
+  const char *name() const override { return "lld"; }
+
+  std::string message(int EV) const override {
+    switch (static_cast<LLDError>(EV)) {
+    case LLDError::InvalidOption:
+      return "Invalid option";
+    case LLDError::InvalidFile:
+      return "Invalid file";
+    case LLDError::BrokenFile:
+      return "Broken file";
+    case LLDError::DuplicateSymbols:
+      return "Duplicate symbols";
+    }
+    llvm_unreachable("unknown error");
+  }
+};
+
+inline std::error_code make_error_code(LLDError Err) {
+  static LLDErrorCategory C;
+  return std::error_code(static_cast<int>(Err), C);
+}
+
+} // namespace coff
+} // namespace lld
+
+#endif

Modified: lld/trunk/COFF/InputFiles.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/InputFiles.cpp?rev=238714&r1=238713&r2=238714&view=diff
==============================================================================
--- lld/trunk/COFF/InputFiles.cpp (original)
+++ lld/trunk/COFF/InputFiles.cpp Sun May 31 21:58:15 2015
@@ -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"
@@ -93,7 +93,8 @@ std::error_code ObjectFile::parse() {
     Bin.release();
     COFFObj.reset(Obj);
   } else {
-    return make_dynamic_error_code(getName() + " is not a COFF file.");
+    llvm::errs() << getName() << " is not a COFF file.\n";
+    return make_error_code(LLDError::InvalidFile);
   }
 
   // Read section and symbol tables.
@@ -113,12 +114,16 @@ std::error_code ObjectFile::initializeCh
   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(LLDError::BrokenFile);
+    }
+    if (auto EC = COFFObj->getSectionName(Sec, Name)) {
+      llvm::errs() << "getSectionName failed: " << Name << ": "
+                   << EC.message() << "\n";
+      return make_error_code(LLDError::BrokenFile);
+    }
     if (Name == ".drectve") {
       ArrayRef<uint8_t> Data;
       COFFObj->getSectionContents(Sec, Data);
@@ -144,16 +149,20 @@ std::error_code ObjectFile::initializeSy
   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("broken object file: " + getName() +
-                                     ": " + EC.message());
+    if (auto EC = SymOrErr.getError()) {
+      llvm::errs() << "broken object file: " << getName() << ": "
+                   << EC.message() << "\n";
+      return make_error_code(LLDError::BrokenFile);
+    }
     COFFSymbolRef Sym = SymOrErr.get();
 
     // Get a symbol name.
     StringRef SymbolName;
-    if (auto EC = COFFObj->getSymbolName(Sym, SymbolName))
-      return make_dynamic_error_code("broken object file: " + getName() +
-                                     ": " + EC.message());
+    if (auto EC = COFFObj->getSymbolName(Sym, SymbolName)) {
+      llvm::errs() << "broken object file: " << getName() << ": "
+                   << EC.message() << "\n";
+      return make_error_code(LLDError::BrokenFile);
+    }
     // Skip special symbols.
     if (SymbolName == "@comp.id" || SymbolName == "@feat.00")
       continue;
@@ -210,8 +219,10 @@ std::error_code ImportFile::parse() {
   const auto *Hdr = reinterpret_cast<const coff_import_header *>(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(LLDError::BrokenFile);
+  }
 
   // Read names and create an __imp_ symbol.
   StringRef Name = StringAlloc.save(StringRef(Buf + sizeof(*Hdr)));

Modified: lld/trunk/COFF/SymbolTable.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/SymbolTable.cpp?rev=238714&r1=238713&r2=238714&view=diff
==============================================================================
--- lld/trunk/COFF/SymbolTable.cpp (original)
+++ lld/trunk/COFF/SymbolTable.cpp Sun May 31 21:58:15 2015
@@ -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"
@@ -115,8 +115,10 @@ std::error_code SymbolTable::resolve(Sym
   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::errs() << "duplicate symbol: " << Name << "\n";
+    return make_error_code(LLDError::DuplicateSymbols);
+  }
 
   // If we have an Undefined symbol for a Lazy symbol, we need
   // to read an archive member to replace the Lazy symbol with
@@ -180,7 +182,8 @@ ErrorOr<StringRef> SymbolTable::findDefa
       return EC;
     return StringRef(E[1]);
   }
-  return make_dynamic_error_code("entry point must be defined");
+  llvm::errs() << "entry point must be defined\n";
+  return make_error_code(LLDError::InvalidOption);
 }
 
 std::error_code SymbolTable::addUndefined(StringRef Name) {

Modified: lld/trunk/COFF/Symbols.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Symbols.cpp?rev=238714&r1=238713&r2=238714&view=diff
==============================================================================
--- lld/trunk/COFF/Symbols.cpp (original)
+++ lld/trunk/COFF/Symbols.cpp Sun May 31 21:58:15 2015
@@ -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 @@ ErrorOr<std::unique_ptr<InputFile>> Lazy
   if (Magic == file_magic::coff_import_library)
     return std::unique_ptr<InputFile>(new ImportFile(MBRef));
 
-  if (Magic != file_magic::coff_object)
-    return make_dynamic_error_code("unknown file type");
+  if (Magic != file_magic::coff_object) {
+    llvm::errs() << File->getName() << ": unknown file type\n";
+    return make_error_code(LLDError::InvalidFile);
+  }
 
   std::unique_ptr<InputFile> Obj(new ObjectFile(MBRef));
   Obj->setParentName(File->getName());

Modified: lld/trunk/COFF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Writer.cpp?rev=238714&r1=238713&r2=238714&view=diff
==============================================================================
--- lld/trunk/COFF/Writer.cpp (original)
+++ lld/trunk/COFF/Writer.cpp Sun May 31 21:58:15 2015
@@ -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"
@@ -356,9 +355,10 @@ void Writer::writeHeader() {
 
 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();
 }
 





More information about the llvm-commits mailing list