[lld] r259069 - ELF: Rename error -> fatal and redefine error as a non-noreturn function.

Rui Ueyama via llvm-commits llvm-commits at lists.llvm.org
Thu Jan 28 10:40:06 PST 2016


Author: ruiu
Date: Thu Jan 28 12:40:06 2016
New Revision: 259069

URL: http://llvm.org/viewvc/llvm-project?rev=259069&view=rev
Log:
ELF: Rename error -> fatal and redefine error as a non-noreturn function.

In many situations, we don't want to exit at the first error even in the
process model. For example, it is better to report all undefined symbols
rather than reporting the first one that the linker picked up randomly.

In order to handle such errors, we don't need to wrap everything with
ErrorOr (thanks for David Blaikie for pointing this out!) Instead, we
can set a flag to record the fact that we found an error and keep it
going until it reaches a reasonable checkpoint.

This idea should be applicable to other places. For example, we can
ignore broken relocations and check for errors after visiting all relocs.

In this patch, I rename error to fatal, and introduce another version of
error which doesn't call exit. That function instead sets HasError to true.
Once HasError becomes true, it stays true, so that we know that there
was an error if it is true.

I think introducing a non-noreturn error reporting function is by itself
a good idea, and it looks to me that this also provides a gradual path
towards lld-as-a-library (or at least embed-lld-to-your-program) without
sacrificing code readability with lots of ErrorOr's.

http://reviews.llvm.org/D16641

Modified:
    lld/trunk/ELF/Driver.cpp
    lld/trunk/ELF/Driver.h
    lld/trunk/ELF/DriverUtils.cpp
    lld/trunk/ELF/Error.cpp
    lld/trunk/ELF/Error.h
    lld/trunk/ELF/InputFiles.cpp
    lld/trunk/ELF/InputSection.cpp
    lld/trunk/ELF/LinkerScript.cpp
    lld/trunk/ELF/OutputSections.cpp
    lld/trunk/ELF/SymbolTable.cpp
    lld/trunk/ELF/Target.cpp
    lld/trunk/ELF/Writer.cpp
    lld/trunk/include/lld/Driver/Driver.h
    lld/trunk/lib/Driver/UniversalDriver.cpp

Modified: lld/trunk/ELF/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Driver.cpp?rev=259069&r1=259068&r2=259069&view=diff
==============================================================================
--- lld/trunk/ELF/Driver.cpp (original)
+++ lld/trunk/ELF/Driver.cpp Thu Jan 28 12:40:06 2016
@@ -29,12 +29,14 @@ using namespace lld::elf2;
 Configuration *elf2::Config;
 LinkerDriver *elf2::Driver;
 
-void elf2::link(ArrayRef<const char *> Args) {
+bool elf2::link(ArrayRef<const char *> Args) {
+  HasError = false;
   Configuration C;
   LinkerDriver D;
   Config = &C;
   Driver = &D;
   Driver->main(Args.slice(1));
+  return !HasError;
 }
 
 static std::pair<ELFKind, uint16_t> parseEmulation(StringRef S) {
@@ -53,22 +55,22 @@ static std::pair<ELFKind, uint16_t> pars
   if (S == "aarch64linux")
     return {ELF64LEKind, EM_AARCH64};
   if (S == "i386pe" || S == "i386pep" || S == "thumb2pe")
-    error("Windows targets are not supported on the ELF frontend: " + S);
-  error("Unknown emulation: " + S);
+    fatal("Windows targets are not supported on the ELF frontend: " + S);
+  fatal("Unknown emulation: " + S);
 }
 
 // Returns slices of MB by parsing MB as an archive file.
 // Each slice consists of a member file in the archive.
 static std::vector<MemoryBufferRef> getArchiveMembers(MemoryBufferRef MB) {
   ErrorOr<std::unique_ptr<Archive>> FileOrErr = Archive::create(MB);
-  error(FileOrErr, "Failed to parse archive");
+  fatal(FileOrErr, "Failed to parse archive");
   std::unique_ptr<Archive> File = std::move(*FileOrErr);
 
   std::vector<MemoryBufferRef> V;
   for (const ErrorOr<Archive::Child> &C : File->children()) {
-    error(C, "Could not get the child of the archive " + File->getFileName());
+    fatal(C, "Could not get the child of the archive " + File->getFileName());
     ErrorOr<MemoryBufferRef> MbOrErr = C->getMemoryBufferRef();
-    error(MbOrErr, "Could not get the buffer for a child of the archive " +
+    fatal(MbOrErr, "Could not get the buffer for a child of the archive " +
                        File->getFileName());
     V.push_back(*MbOrErr);
   }
@@ -82,7 +84,7 @@ void LinkerDriver::addFile(StringRef Pat
   if (Config->Verbose)
     llvm::outs() << Path << "\n";
   auto MBOrErr = MemoryBuffer::getFile(Path);
-  error(MBOrErr, "cannot open " + Path);
+  fatal(MBOrErr, "cannot open " + Path);
   std::unique_ptr<MemoryBuffer> &MB = *MBOrErr;
   MemoryBufferRef MBRef = MB->getMemBufferRef();
   OwningMBs.push_back(std::move(MB)); // take MB ownership
@@ -114,15 +116,15 @@ static void checkOptions(opt::InputArgLi
   // of executables or DSOs. We don't support that since the feature
   // does not seem to provide more value than the static archiver.
   if (Args.hasArg(OPT_relocatable))
-    error("-r option is not supported. Use 'ar' command instead.");
+    fatal("-r option is not supported. Use 'ar' command instead.");
 
   // The MIPS ABI as of 2016 does not support the GNU-style symbol lookup
   // table which is a relatively new feature.
   if (Config->EMachine == EM_MIPS && Config->GnuHash)
-    error("The .gnu.hash section is not compatible with the MIPS target.");
+    fatal("The .gnu.hash section is not compatible with the MIPS target.");
 
   if (Config->EMachine == EM_AMDGPU && !Config->Entry.empty())
-    error("-e option is not valid for AMDGPU.");
+    fatal("-e option is not valid for AMDGPU.");
 }
 
 static StringRef
@@ -161,7 +163,7 @@ void LinkerDriver::main(ArrayRef<const c
     link<ELF64BE>(Args);
     return;
   default:
-    error("-m or at least a .o file required");
+    fatal("-m or at least a .o file required");
   }
 }
 
@@ -217,7 +219,7 @@ void LinkerDriver::readConfigs(opt::Inpu
   if (auto *Arg = Args.getLastArg(OPT_O)) {
     StringRef Val = Arg->getValue();
     if (Val.getAsInteger(10, Config->Optimize))
-      error("Invalid optimization level");
+      fatal("Invalid optimization level");
   }
 
   if (auto *Arg = Args.getLastArg(OPT_hash_style)) {
@@ -228,7 +230,7 @@ void LinkerDriver::readConfigs(opt::Inpu
     } else if (S == "both") {
       Config->GnuHash = true;
     } else if (S != "sysv")
-      error("Unknown hash style: " + S);
+      fatal("Unknown hash style: " + S);
   }
 
   for (auto *Arg : Args.filtered(OPT_undefined))
@@ -267,7 +269,7 @@ void LinkerDriver::createFiles(opt::Inpu
   }
 
   if (Files.empty())
-    error("no input files.");
+    fatal("no input files.");
 }
 
 template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) {

Modified: lld/trunk/ELF/Driver.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Driver.h?rev=259069&r1=259068&r2=259069&view=diff
==============================================================================
--- lld/trunk/ELF/Driver.h (original)
+++ lld/trunk/ELF/Driver.h Thu Jan 28 12:40:06 2016
@@ -20,8 +20,8 @@ namespace elf2 {
 
 extern class LinkerDriver *Driver;
 
-// Entry point of the ELF linker.
-void link(ArrayRef<const char *> Args);
+// Entry point of the ELF linker. Returns true on success.
+bool link(ArrayRef<const char *> Args);
 
 class LinkerDriver {
 public:

Modified: lld/trunk/ELF/DriverUtils.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/DriverUtils.cpp?rev=259069&r1=259068&r2=259069&view=diff
==============================================================================
--- lld/trunk/ELF/DriverUtils.cpp (original)
+++ lld/trunk/ELF/DriverUtils.cpp Thu Jan 28 12:40:06 2016
@@ -66,7 +66,7 @@ opt::InputArgList elf2::parseArgs(llvm::
   // Parse options and then do error checking.
   opt::InputArgList Args = Table.ParseArgs(Vec, MissingIndex, MissingCount);
   if (MissingCount)
-    error(Twine("missing arg value for \"") + Args.getArgString(MissingIndex) +
+    fatal(Twine("missing arg value for \"") + Args.getArgString(MissingIndex) +
           "\", expected " + Twine(MissingCount) +
           (MissingCount == 1 ? " argument.\n" : " arguments"));
 
@@ -74,7 +74,7 @@ opt::InputArgList elf2::parseArgs(llvm::
   for (auto *Arg : Unknowns)
     warning("warning: unknown argument: " + Arg->getSpelling());
   if (Unknowns.begin() != Unknowns.end())
-    error("unknown argument(s) found");
+    fatal("unknown argument(s) found");
 
   return Args;
 }
@@ -104,7 +104,7 @@ std::string elf2::searchLibrary(StringRe
     if (!S.empty())
       return S;
   }
-  error("Unable to find library -l" + Path);
+  fatal("Unable to find library -l" + Path);
 }
 
 // Makes a path by concatenating Dir and File.

Modified: lld/trunk/ELF/Error.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Error.cpp?rev=259069&r1=259068&r2=259069&view=diff
==============================================================================
--- lld/trunk/ELF/Error.cpp (original)
+++ lld/trunk/ELF/Error.cpp Thu Jan 28 12:40:06 2016
@@ -15,23 +15,38 @@
 namespace lld {
 namespace elf2 {
 
+bool HasError;
+
 void warning(const Twine &Msg) { llvm::errs() << Msg << "\n"; }
 
 void error(const Twine &Msg) {
   llvm::errs() << Msg << "\n";
-  exit(1);
+  HasError = true;
 }
 
 void error(std::error_code EC, const Twine &Prefix) {
-  if (!EC)
-    return;
-  error(Prefix + ": " + EC.message());
+  if (EC)
+    error(Prefix + ": " + EC.message());
 }
 
 void error(std::error_code EC) {
-  if (!EC)
-    return;
-  error(EC.message());
+  if (EC)
+    error(EC.message());
+}
+
+void fatal(const Twine &Msg) {
+  llvm::errs() << Msg << "\n";
+  exit(1);
+}
+
+void fatal(std::error_code EC, const Twine &Prefix) {
+  if (EC)
+    fatal(Prefix + ": " + EC.message());
+}
+
+void fatal(std::error_code EC) {
+  if (EC)
+    fatal(EC.message());
 }
 
 } // namespace elf2

Modified: lld/trunk/ELF/Error.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Error.h?rev=259069&r1=259068&r2=259069&view=diff
==============================================================================
--- lld/trunk/ELF/Error.h (original)
+++ lld/trunk/ELF/Error.h Thu Jan 28 12:40:06 2016
@@ -15,9 +15,11 @@
 namespace lld {
 namespace elf2 {
 
+extern bool HasError;
+
 void warning(const Twine &Msg);
 
-LLVM_ATTRIBUTE_NORETURN void error(const Twine &Msg);
+void error(const Twine &Msg);
 void error(std::error_code EC, const Twine &Prefix);
 void error(std::error_code EC);
 
@@ -26,6 +28,15 @@ template <typename T> void error(const E
 }
 template <typename T> void error(const ErrorOr<T> &V) { error(V.getError()); }
 
+LLVM_ATTRIBUTE_NORETURN void fatal(const Twine &Msg);
+void fatal(std::error_code EC, const Twine &Prefix);
+void fatal(std::error_code EC);
+
+template <typename T> void fatal(const ErrorOr<T> &V, const Twine &Prefix) {
+  fatal(V.getError(), Prefix);
+}
+template <typename T> void fatal(const ErrorOr<T> &V) { fatal(V.getError()); }
+
 } // namespace elf2
 } // namespace lld
 

Modified: lld/trunk/ELF/InputFiles.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputFiles.cpp?rev=259069&r1=259068&r2=259069&view=diff
==============================================================================
--- lld/trunk/ELF/InputFiles.cpp (original)
+++ lld/trunk/ELF/InputFiles.cpp Thu Jan 28 12:40:06 2016
@@ -27,7 +27,7 @@ class ECRAII {
 
 public:
   std::error_code &getEC() { return EC; }
-  ~ECRAII() { error(EC); }
+  ~ECRAII() { fatal(EC); }
 };
 }
 
@@ -51,7 +51,7 @@ ELFFileBase<ELFT>::getSymbolsHelper(bool
   uint32_t NumSymbols = std::distance(Syms.begin(), Syms.end());
   uint32_t FirstNonLocal = Symtab->sh_info;
   if (FirstNonLocal > NumSymbols)
-    error("Invalid sh_info in symbol table");
+    fatal("Invalid sh_info in symbol table");
   if (!Local)
     return make_range(Syms.begin() + FirstNonLocal, Syms.end());
   // +1 to skip over dummy symbol.
@@ -72,7 +72,7 @@ template <class ELFT> void ELFFileBase<E
   if (!Symtab)
     return;
   ErrorOr<StringRef> StringTableOrErr = ELFObj.getStringTableForSymtab(*Symtab);
-  error(StringTableOrErr);
+  fatal(StringTableOrErr);
   StringTable = *StringTableOrErr;
 }
 
@@ -122,14 +122,14 @@ StringRef ObjectFile<ELFT>::getShtGroupS
   const ELFFile<ELFT> &Obj = this->ELFObj;
   uint32_t SymtabdSectionIndex = Sec.sh_link;
   ErrorOr<const Elf_Shdr *> SecOrErr = Obj.getSection(SymtabdSectionIndex);
-  error(SecOrErr);
+  fatal(SecOrErr);
   const Elf_Shdr *SymtabSec = *SecOrErr;
   uint32_t SymIndex = Sec.sh_info;
   const Elf_Sym *Sym = Obj.getSymbol(SymtabSec, SymIndex);
   ErrorOr<StringRef> StringTableOrErr = Obj.getStringTableForSymtab(*SymtabSec);
-  error(StringTableOrErr);
+  fatal(StringTableOrErr);
   ErrorOr<StringRef> SignatureOrErr = Sym->getName(*StringTableOrErr);
-  error(SignatureOrErr);
+  fatal(SignatureOrErr);
   return *SignatureOrErr;
 }
 
@@ -139,10 +139,10 @@ ObjectFile<ELFT>::getShtGroupEntries(con
   const ELFFile<ELFT> &Obj = this->ELFObj;
   ErrorOr<ArrayRef<uint32_X>> EntriesOrErr =
       Obj.template getSectionContentsAsArray<uint32_X>(&Sec);
-  error(EntriesOrErr);
+  fatal(EntriesOrErr);
   ArrayRef<uint32_X> Entries = *EntriesOrErr;
   if (Entries.empty() || Entries[0] != GRP_COMDAT)
-    error("Unsupported SHT_GROUP format");
+    fatal("Unsupported SHT_GROUP format");
   return Entries.slice(1);
 }
 
@@ -153,10 +153,10 @@ static bool shouldMerge(const typename E
   if (!(Flags & SHF_MERGE))
     return false;
   if (Flags & SHF_WRITE)
-    error("Writable SHF_MERGE sections are not supported");
+    fatal("Writable SHF_MERGE sections are not supported");
   uintX_t EntSize = Sec.sh_entsize;
   if (!EntSize || Sec.sh_size % EntSize)
-    error("SHF_MERGE section size must be a multiple of sh_entsize");
+    fatal("SHF_MERGE section size must be a multiple of sh_entsize");
 
   // Don't try to merge if the aligment is larger than the sh_entsize.
   //
@@ -191,7 +191,7 @@ void ObjectFile<ELFT>::initializeSection
         continue;
       for (uint32_t SecIndex : getShtGroupEntries(Sec)) {
         if (SecIndex >= Size)
-          error("Invalid section index in group");
+          fatal("Invalid section index in group");
         Sections[SecIndex] = &InputSection<ELFT>::Discarded;
       }
       break;
@@ -200,7 +200,7 @@ void ObjectFile<ELFT>::initializeSection
       break;
     case SHT_SYMTAB_SHNDX: {
       ErrorOr<ArrayRef<Elf_Word>> ErrorOrTable = Obj.getSHNDXTable(Sec);
-      error(ErrorOrTable);
+      fatal(ErrorOrTable);
       this->SymtabSHNDX = *ErrorOrTable;
       break;
     }
@@ -211,19 +211,19 @@ void ObjectFile<ELFT>::initializeSection
     case SHT_REL: {
       uint32_t RelocatedSectionIndex = Sec.sh_info;
       if (RelocatedSectionIndex >= Size)
-        error("Invalid relocated section index");
+        fatal("Invalid relocated section index");
       InputSectionBase<ELFT> *RelocatedSection =
           Sections[RelocatedSectionIndex];
       if (!RelocatedSection)
-        error("Unsupported relocation reference");
+        fatal("Unsupported relocation reference");
       if (auto *S = dyn_cast<InputSection<ELFT>>(RelocatedSection)) {
         S->RelocSections.push_back(&Sec);
       } else if (auto *S = dyn_cast<EHInputSection<ELFT>>(RelocatedSection)) {
         if (S->RelocSection)
-          error("Multiple relocation sections to .eh_frame are not supported");
+          fatal("Multiple relocation sections to .eh_frame are not supported");
         S->RelocSection = &Sec;
       } else {
-        error("Relocations pointing to SHF_MERGE are not supported");
+        fatal("Relocations pointing to SHF_MERGE are not supported");
       }
       break;
     }
@@ -236,7 +236,7 @@ void ObjectFile<ELFT>::initializeSection
 template <class ELFT> InputSectionBase<ELFT> *
 ObjectFile<ELFT>::createInputSection(const Elf_Shdr &Sec) {
   ErrorOr<StringRef> NameOrErr = this->ELFObj.getSectionName(&Sec);
-  error(NameOrErr);
+  fatal(NameOrErr);
   StringRef Name = *NameOrErr;
 
   // .note.GNU-stack is a marker section to control the presence of
@@ -276,14 +276,14 @@ ObjectFile<ELFT>::getSection(const Elf_S
   if (Index == 0)
     return nullptr;
   if (Index >= Sections.size() || !Sections[Index])
-    error("Invalid section index");
+    fatal("Invalid section index");
   return Sections[Index];
 }
 
 template <class ELFT>
 SymbolBody *ObjectFile<ELFT>::createSymbolBody(const Elf_Sym *Sym) {
   ErrorOr<StringRef> NameOrErr = Sym->getName(this->StringTable);
-  error(NameOrErr);
+  fatal(NameOrErr);
   StringRef Name = *NameOrErr;
 
   switch (Sym->st_shndx) {
@@ -297,7 +297,7 @@ SymbolBody *ObjectFile<ELFT>::createSymb
 
   switch (Sym->getBinding()) {
   default:
-    error("unexpected binding");
+    fatal("unexpected binding");
   case STB_GLOBAL:
   case STB_WEAK:
   case STB_GNU_UNIQUE: {
@@ -311,7 +311,7 @@ SymbolBody *ObjectFile<ELFT>::createSymb
 
 void ArchiveFile::parse() {
   ErrorOr<std::unique_ptr<Archive>> FileOrErr = Archive::create(MB);
-  error(FileOrErr, "Failed to parse archive");
+  fatal(FileOrErr, "Failed to parse archive");
   File = std::move(*FileOrErr);
 
   // Allocate a buffer for Lazy objects.
@@ -326,7 +326,7 @@ void ArchiveFile::parse() {
 // Returns a buffer pointing to a member file containing a given symbol.
 MemoryBufferRef ArchiveFile::getMember(const Archive::Symbol *Sym) {
   ErrorOr<Archive::Child> COrErr = Sym->getMember();
-  error(COrErr, "Could not get the member for symbol " + Sym->getName());
+  fatal(COrErr, "Could not get the member for symbol " + Sym->getName());
   const Archive::Child &C = *COrErr;
 
   if (!Seen.insert(C.getChildOffset()).second)
@@ -334,8 +334,8 @@ MemoryBufferRef ArchiveFile::getMember(c
 
   ErrorOr<MemoryBufferRef> RefOrErr = C.getMemoryBufferRef();
   if (!RefOrErr)
-    error(RefOrErr, "Could not get the buffer for the member defining symbol " +
-          Sym->getName());
+    fatal(RefOrErr, "Could not get the buffer for the member defining symbol " +
+                        Sym->getName());
   return *RefOrErr;
 }
 
@@ -350,7 +350,7 @@ SharedFile<ELFT>::getSection(const Elf_S
   if (Index == 0)
     return nullptr;
   ErrorOr<const Elf_Shdr *> Ret = this->ELFObj.getSection(Index);
-  error(Ret);
+  fatal(Ret);
   return *Ret;
 }
 
@@ -374,7 +374,7 @@ template <class ELFT> void SharedFile<EL
       break;
     case SHT_SYMTAB_SHNDX: {
       ErrorOr<ArrayRef<Elf_Word>> ErrorOrTable = Obj.getSHNDXTable(Sec);
-      error(ErrorOrTable);
+      fatal(ErrorOrTable);
       this->SymtabSHNDX = *ErrorOrTable;
       break;
     }
@@ -394,7 +394,7 @@ template <class ELFT> void SharedFile<EL
     if (Dyn.d_tag == DT_SONAME) {
       uintX_t Val = Dyn.getVal();
       if (Val >= this->StringTable.size())
-        error("Invalid DT_SONAME entry");
+        fatal("Invalid DT_SONAME entry");
       SoName = StringRef(this->StringTable.data() + Val);
       return;
     }
@@ -408,7 +408,7 @@ template <class ELFT> void SharedFile<EL
   SymbolBodies.reserve(NumSymbols);
   for (const Elf_Sym &Sym : Syms) {
     ErrorOr<StringRef> NameOrErr = Sym.getName(this->StringTable);
-    error(NameOrErr.getError());
+    fatal(NameOrErr.getError());
     StringRef Name = *NameOrErr;
 
     if (Sym.isUndefined())
@@ -437,7 +437,7 @@ template <template <class> class T>
 static std::unique_ptr<InputFile> createELFFile(MemoryBufferRef MB) {
   std::pair<unsigned char, unsigned char> Type = getElfArchType(MB.getBuffer());
   if (Type.second != ELF::ELFDATA2LSB && Type.second != ELF::ELFDATA2MSB)
-    error("Invalid data encoding: " + MB.getBufferIdentifier());
+    fatal("Invalid data encoding: " + MB.getBufferIdentifier());
 
   if (Type.first == ELF::ELFCLASS32) {
     if (Type.second == ELF::ELFDATA2LSB)
@@ -449,7 +449,7 @@ static std::unique_ptr<InputFile> create
       return createELFFileAux<T<ELF64LE>>(MB);
     return createELFFileAux<T<ELF64BE>>(MB);
   }
-  error("Invalid file class: " + MB.getBufferIdentifier());
+  fatal("Invalid file class: " + MB.getBufferIdentifier());
 }
 
 std::unique_ptr<InputFile> elf2::createObjectFile(MemoryBufferRef MB) {

Modified: lld/trunk/ELF/InputSection.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputSection.cpp?rev=259069&r1=259068&r2=259069&view=diff
==============================================================================
--- lld/trunk/ELF/InputSection.cpp (original)
+++ lld/trunk/ELF/InputSection.cpp Thu Jan 28 12:40:06 2016
@@ -29,7 +29,7 @@ InputSectionBase<ELFT>::InputSectionBase
 
 template <class ELFT> StringRef InputSectionBase<ELFT>::getSectionName() const {
   ErrorOr<StringRef> Name = File->getObj().getSectionName(this->Header);
-  error(Name);
+  fatal(Name);
   return *Name;
 }
 
@@ -37,7 +37,7 @@ template <class ELFT>
 ArrayRef<uint8_t> InputSectionBase<ELFT>::getSectionData() const {
   ErrorOr<ArrayRef<uint8_t>> Ret =
       this->File->getObj().getSectionContents(this->Header);
-  error(Ret);
+  fatal(Ret);
   return *Ret;
 }
 
@@ -325,7 +325,7 @@ SplitInputSection<ELFT>::getRangeAndSize
   StringRef Data((const char *)D.data(), D.size());
   uintX_t Size = Data.size();
   if (Offset >= Size)
-    error("Entry is past the end of the section");
+    fatal("Entry is past the end of the section");
 
   // Find the element this offset points to.
   auto I = std::upper_bound(
@@ -369,7 +369,7 @@ MipsReginfoInputSection<ELFT>::MipsRegin
   // Initialize this->Reginfo.
   ArrayRef<uint8_t> D = this->getSectionData();
   if (D.size() != sizeof(Elf_Mips_RegInfo<ELFT>))
-    error("Invalid size of .reginfo section");
+    fatal("Invalid size of .reginfo section");
   Reginfo = reinterpret_cast<const Elf_Mips_RegInfo<ELFT> *>(D.data());
 }
 

Modified: lld/trunk/ELF/LinkerScript.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LinkerScript.cpp?rev=259069&r1=259068&r2=259069&view=diff
==============================================================================
--- lld/trunk/ELF/LinkerScript.cpp (original)
+++ lld/trunk/ELF/LinkerScript.cpp Thu Jan 28 12:40:06 2016
@@ -86,7 +86,7 @@ void LinkerScript::run() {
     } else if (Tok == "SECTIONS") {
       readSections();
     } else {
-      error("unknown directive: " + Tok);
+      fatal("unknown directive: " + Tok);
     }
   }
 }
@@ -103,7 +103,7 @@ std::vector<StringRef> LinkerScript::tok
     if (S.startswith("\"")) {
       size_t E = S.find("\"", 1);
       if (E == StringRef::npos)
-        error("unclosed quote");
+        fatal("unclosed quote");
       Ret.push_back(S.substr(1, E - 1));
       S = S.substr(E + 1);
       continue;
@@ -128,7 +128,7 @@ StringRef LinkerScript::skipSpace(String
     if (S.startswith("/*")) {
       size_t E = S.find("*/", 2);
       if (E == StringRef::npos)
-        error("unclosed comment in a linker script");
+        fatal("unclosed comment in a linker script");
       S = S.substr(E + 2);
       continue;
     }
@@ -141,13 +141,13 @@ StringRef LinkerScript::skipSpace(String
 
 StringRef LinkerScript::next() {
   if (atEOF())
-    error("unexpected EOF");
+    fatal("unexpected EOF");
   return Tokens[Pos++];
 }
 
 bool LinkerScript::skip(StringRef Tok) {
   if (atEOF())
-    error("unexpected EOF");
+    fatal("unexpected EOF");
   if (Tok != Tokens[Pos])
     return false;
   ++Pos;
@@ -157,7 +157,7 @@ bool LinkerScript::skip(StringRef Tok) {
 void LinkerScript::expect(StringRef Expect) {
   StringRef Tok = next();
   if (Tok != Expect)
-    error(Expect + " expected, but got " + Tok);
+    fatal(Expect + " expected, but got " + Tok);
 }
 
 void LinkerScript::addFile(StringRef S) {
@@ -184,7 +184,7 @@ void LinkerScript::addFile(StringRef S)
   } else {
     std::string Path = findFromSearchPaths(S);
     if (Path.empty())
-      error("Unable to find " + S);
+      fatal("Unable to find " + S);
     Driver->addFile(Saver.save(Path));
   }
 }
@@ -238,7 +238,7 @@ void LinkerScript::readGroup() {
 void LinkerScript::readInclude() {
   StringRef Tok = next();
   auto MBOrErr = MemoryBuffer::getFile(Tok);
-  error(MBOrErr, "cannot open " + Tok);
+  fatal(MBOrErr, "cannot open " + Tok);
   std::unique_ptr<MemoryBuffer> &MB = *MBOrErr;
   StringRef S = Saver.save(MB->getMemBufferRef().getBuffer());
   std::vector<StringRef> V = tokenize(S);
@@ -269,7 +269,7 @@ void LinkerScript::readOutputFormat() {
   if (Tok == ")")
    return;
   if (Tok != ",")
-    error("unexpected token: " + Tok);
+    fatal("unexpected token: " + Tok);
   next();
   expect(",");
   next();

Modified: lld/trunk/ELF/OutputSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.cpp?rev=259069&r1=259068&r2=259069&view=diff
==============================================================================
--- lld/trunk/ELF/OutputSections.cpp (original)
+++ lld/trunk/ELF/OutputSections.cpp Thu Jan 28 12:40:06 2016
@@ -770,7 +770,7 @@ EhFrameHeader<ELFT>::getFdePc(uintX_t Eh
       return FdeOff + read64<E>(F.PCRel);
     return FdeOff + read32<E>(F.PCRel);
   }
-  error("unknown FDE size encoding");
+  fatal("unknown FDE size encoding");
 }
 
 template <class ELFT> void EhFrameHeader<ELFT>::writeTo(uint8_t *Buf) {
@@ -813,7 +813,7 @@ void EhFrameHeader<ELFT>::assignEhFrame(
 template <class ELFT>
 void EhFrameHeader<ELFT>::addFde(uint8_t Enc, size_t Off, uint8_t *PCRel) {
   if (Live && (Enc & 0xF0) == dwarf::DW_EH_PE_datarel)
-    error("DW_EH_PE_datarel encoding unsupported for FDEs by .eh_frame_hdr");
+    fatal("DW_EH_PE_datarel encoding unsupported for FDEs by .eh_frame_hdr");
   FdeList.push_back(FdeData{Enc, Off, PCRel});
 }
 
@@ -904,7 +904,7 @@ elf2::getLocalRelTarget(const ObjectFile
       File.getObj().getRelocationSymbol(&RI, File.getSymbolTable());
 
   if (!Sym)
-    error("Unsupported relocation without symbol");
+    fatal("Unsupported relocation without symbol");
 
   InputSectionBase<ELFT> *Section = File.getSection(*Sym);
 
@@ -1001,7 +1001,7 @@ Cie<ELFT>::Cie(EHInputSection<ELFT> *S,
 // Read a byte and advance D by one byte.
 static uint8_t readByte(ArrayRef<uint8_t> &D) {
   if (D.empty())
-    error("corrupted or unsupported CIE information");
+    fatal("corrupted or unsupported CIE information");
   uint8_t B = D.front();
   D = D.slice(1);
   return B;
@@ -1014,14 +1014,14 @@ static void skipLeb128(ArrayRef<uint8_t>
     if ((Val & 0x80) == 0)
       return;
   }
-  error("corrupted or unsupported CIE information");
+  fatal("corrupted or unsupported CIE information");
 }
 
 template <class ELFT> static unsigned getSizeForEncoding(unsigned Enc) {
   typedef typename ELFFile<ELFT>::uintX_t uintX_t;
   switch (Enc & 0x0f) {
   default:
-    error("unknown FDE encoding");
+    fatal("unknown FDE encoding");
   case dwarf::DW_EH_PE_absptr:
   case dwarf::DW_EH_PE_signed:
     return sizeof(uintX_t);
@@ -1041,7 +1041,7 @@ template <class ELFT>
 uint8_t EHOutputSection<ELFT>::getFdeEncoding(ArrayRef<uint8_t> D) {
   auto Check = [](bool C) {
     if (!C)
-      error("corrupted or unsupported CIE information");
+      fatal("corrupted or unsupported CIE information");
   };
 
   Check(D.size() >= 8);
@@ -1049,7 +1049,7 @@ uint8_t EHOutputSection<ELFT>::getFdeEnc
 
   uint8_t Version = readByte(D);
   if (Version != 1 && Version != 3)
-    error("FDE version 1 or 3 expected, but got " + Twine((unsigned)Version));
+    fatal("FDE version 1 or 3 expected, but got " + Twine((unsigned)Version));
 
   auto AugEnd = std::find(D.begin() + 1, D.end(), '\0');
   Check(AugEnd != D.end());
@@ -1058,7 +1058,7 @@ uint8_t EHOutputSection<ELFT>::getFdeEnc
 
   // Code alignment factor should always be 1 for .eh_frame.
   if (readByte(D) != 1)
-    error("CIE code alignment must be 1");
+    fatal("CIE code alignment must be 1");
   // Skip data alignment factor
   skipLeb128(D);
 
@@ -1079,7 +1079,7 @@ uint8_t EHOutputSection<ELFT>::getFdeEnc
     case 'P': {
       uint8_t Enc = readByte(D);
       if ((Enc & 0xf0) == dwarf::DW_EH_PE_aligned)
-        error("DW_EH_PE_aligned encoding for address of a personality routine "
+        fatal("DW_EH_PE_aligned encoding for address of a personality routine "
               "handler not supported");
       unsigned EncSize = getSizeForEncoding<ELFT>(Enc);
       Check(D.size() >= EncSize);
@@ -1093,7 +1093,7 @@ uint8_t EHOutputSection<ELFT>::getFdeEnc
       //    handler
       break;
     default:
-      error("unknown .eh_frame augmentation string value");
+      fatal("unknown .eh_frame augmentation string value");
     }
   }
   return dwarf::DW_EH_PE_absptr;
@@ -1159,13 +1159,13 @@ void EHOutputSection<ELFT>::addSectionAu
       OffsetToIndex[Offset] = P.first->second;
     } else {
       if (!HasReloc)
-        error("FDE doesn't reference another section");
+        fatal("FDE doesn't reference another section");
       InputSectionBase<ELFT> *Target = S->getRelocTarget(*RelI);
       if (Target != &InputSection<ELFT>::Discarded && Target->isLive()) {
         uint32_t CieOffset = Offset + 4 - ID;
         auto I = OffsetToIndex.find(CieOffset);
         if (I == OffsetToIndex.end())
-          error("Invalid CIE reference");
+          fatal("Invalid CIE reference");
         Cies[I->second].Fdes.push_back(EHRegion<ELFT>(S, Index));
         Out<ELFT>::EhFrameHdr->reserveFde();
         this->Header.sh_size += alignTo(Length, sizeof(uintX_t));
@@ -1183,23 +1183,23 @@ EHOutputSection<ELFT>::readEntryLength(A
   const endianness E = ELFT::TargetEndianness;
 
   if (D.size() < 4)
-    error("Truncated CIE/FDE length");
+    fatal("Truncated CIE/FDE length");
   uint64_t Len = read32<E>(D.data());
   if (Len < UINT32_MAX) {
     if (Len > (UINT32_MAX - 4))
-      error("CIE/FIE size is too large");
+      fatal("CIE/FIE size is too large");
     if (Len + 4 > D.size())
-      error("CIE/FIE ends past the end of the section");
+      fatal("CIE/FIE ends past the end of the section");
     return Len + 4;
   }
 
   if (D.size() < 12)
-    error("Truncated CIE/FDE length");
+    fatal("Truncated CIE/FDE length");
   Len = read64<E>(D.data() + 4);
   if (Len > (UINT64_MAX - 12))
-    error("CIE/FIE size is too large");
+    fatal("CIE/FIE size is too large");
   if (Len + 12 > D.size())
-    error("CIE/FIE ends past the end of the section");
+    fatal("CIE/FIE ends past the end of the section");
   return Len + 12;
 }
 
@@ -1307,7 +1307,7 @@ void MergeOutputSection<ELFT>::addSectio
     while (!Data.empty()) {
       size_t End = findNull(Data, EntSize);
       if (End == StringRef::npos)
-        error("String is not null terminated");
+        fatal("String is not null terminated");
       StringRef Entry = Data.substr(0, End + EntSize);
       uintX_t OutputOffset = Builder.add(Entry);
       if (shouldTailMerge())
@@ -1462,7 +1462,7 @@ void SymbolTableSection<ELFT>::writeLoca
   for (const std::unique_ptr<ObjectFile<ELFT>> &File : Table.getObjectFiles()) {
     for (const Elf_Sym *Sym : File->KeptLocalSyms) {
       ErrorOr<StringRef> SymNameOrErr = Sym->getName(File->getStringTable());
-      error(SymNameOrErr);
+      fatal(SymNameOrErr);
       StringRef SymName = *SymNameOrErr;
 
       auto *ESym = reinterpret_cast<Elf_Sym *>(Buf);

Modified: lld/trunk/ELF/SymbolTable.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SymbolTable.cpp?rev=259069&r1=259068&r2=259069&view=diff
==============================================================================
--- lld/trunk/ELF/SymbolTable.cpp (original)
+++ lld/trunk/ELF/SymbolTable.cpp Thu Jan 28 12:40:06 2016
@@ -41,7 +41,7 @@ static void checkCompatibility(InputFile
   StringRef B = Config->Emulation;
   if (B.empty())
     B = Config->FirstElf->getName();
-  error(A + " is incompatible with " + B);
+  fatal(A + " is incompatible with " + B);
 }
 
 // Add symbols in File to the symbol table.
@@ -182,7 +182,7 @@ template <class ELFT> void SymbolTable<E
   }
 
   if (New->isTls() != Existing->isTls())
-    error("TLS attribute mismatch for symbol: " + conflictMsg(Existing, New));
+    fatal("TLS attribute mismatch for symbol: " + conflictMsg(Existing, New));
 
   // compare() returns -1, 0, or 1 if the lhs symbol is less preferable,
   // equivalent (conflicting), or more preferable, respectively.
@@ -190,7 +190,7 @@ template <class ELFT> void SymbolTable<E
   if (Comp == 0) {
     std::string S = "duplicate symbol: " + conflictMsg(Existing, New);
     if (!Config->AllowMultipleDefinition)
-      error(S);
+      fatal(S);
     warning(S);
     return;
   }

Modified: lld/trunk/ELF/Target.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Target.cpp?rev=259069&r1=259068&r2=259069&view=diff
==============================================================================
--- lld/trunk/ELF/Target.cpp (original)
+++ lld/trunk/ELF/Target.cpp Thu Jan 28 12:40:06 2016
@@ -46,28 +46,28 @@ template <unsigned N> static void checkI
   if (isInt<N>(V))
     return;
   StringRef S = getELFRelocationTypeName(Config->EMachine, Type);
-  error("Relocation " + S + " out of range");
+  fatal("Relocation " + S + " out of range");
 }
 
 template <unsigned N> static void checkUInt(uint64_t V, uint32_t Type) {
   if (isUInt<N>(V))
     return;
   StringRef S = getELFRelocationTypeName(Config->EMachine, Type);
-  error("Relocation " + S + " out of range");
+  fatal("Relocation " + S + " out of range");
 }
 
 template <unsigned N> static void checkIntUInt(uint64_t V, uint32_t Type) {
   if (isInt<N>(V) || isUInt<N>(V))
     return;
   StringRef S = getELFRelocationTypeName(Config->EMachine, Type);
-  error("Relocation " + S + " out of range");
+  fatal("Relocation " + S + " out of range");
 }
 
 template <unsigned N> static void checkAlignment(uint64_t V, uint32_t Type) {
   if ((V & (N - 1)) == 0)
     return;
   StringRef S = getELFRelocationTypeName(Config->EMachine, Type);
-  error("Improper alignment for relocation " + S);
+  fatal("Improper alignment for relocation " + S);
 }
 
 template <class ELFT> bool isGnuIFunc(const SymbolBody &S) {
@@ -260,7 +260,7 @@ TargetInfo *createTarget() {
     case ELF32BEKind:
       return new MipsTargetInfo<ELF32BE>();
     default:
-      error("Unsupported MIPS target");
+      fatal("Unsupported MIPS target");
     }
   case EM_PPC:
     return new PPCTargetInfo();
@@ -269,7 +269,7 @@ TargetInfo *createTarget() {
   case EM_X86_64:
     return new X86_64TargetInfo();
   }
-  error("Unknown target machine");
+  fatal("Unknown target machine");
 }
 
 TargetInfo::~TargetInfo() {}
@@ -463,7 +463,7 @@ void X86TargetInfo::relocateOne(uint8_t
     write32le(Loc, Out<ELF32LE>::TlsPhdr->p_memsz - SA);
     break;
   default:
-    error("unrecognized reloc " + Twine(Type));
+    fatal("unrecognized reloc " + Twine(Type));
   }
 }
 
@@ -926,7 +926,7 @@ void X86_64TargetInfo::relocateOne(uint8
     write32le(Loc, SA - P);
     break;
   default:
-    error("unrecognized reloc " + Twine(Type));
+    fatal("unrecognized reloc " + Twine(Type));
   }
 }
 
@@ -969,7 +969,7 @@ void PPCTargetInfo::relocateOne(uint8_t
     write16be(Loc, applyPPCLo(SA));
     break;
   default:
-    error("unrecognized reloc " + Twine(Type));
+    fatal("unrecognized reloc " + Twine(Type));
   }
 }
 
@@ -1182,7 +1182,7 @@ void PPC64TargetInfo::relocateOne(uint8_
     write64be(Loc, SA);
     break;
   default:
-    error("unrecognized reloc " + Twine(Type));
+    fatal("unrecognized reloc " + Twine(Type));
   }
 }
 
@@ -1201,7 +1201,7 @@ unsigned AArch64TargetInfo::getDynReloc(
   if (Type == R_AARCH64_ABS32 || Type == R_AARCH64_ABS64)
     return Type;
   StringRef S = getELFRelocationTypeName(EM_AARCH64, Type);
-  error("Relocation " + S + " cannot be used when making a shared object; "
+  fatal("Relocation " + S + " cannot be used when making a shared object; "
                             "recompile with -fPIC.");
 }
 
@@ -1421,7 +1421,7 @@ void AArch64TargetInfo::relocateOne(uint
     break;
   }
   default:
-    error("unrecognized reloc " + Twine(Type));
+    fatal("unrecognized reloc " + Twine(Type));
   }
 }
 
@@ -1472,7 +1472,7 @@ unsigned MipsTargetInfo<ELFT>::getDynRel
   if (Type == R_MIPS_32 || Type == R_MIPS_64)
     return R_MIPS_REL32;
   StringRef S = getELFRelocationTypeName(EM_MIPS, Type);
-  error("Relocation " + S + " cannot be used when making a shared object; "
+  fatal("Relocation " + S + " cannot be used when making a shared object; "
                             "recompile with -fPIC.");
 }
 
@@ -1600,7 +1600,7 @@ void MipsTargetInfo<ELFT>::relocateOne(u
     break;
   }
   default:
-    error("unrecognized reloc " + Twine(Type));
+    fatal("unrecognized reloc " + Twine(Type));
   }
 }
 

Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=259069&r1=259068&r2=259069&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Thu Jan 28 12:40:06 2016
@@ -162,7 +162,7 @@ template <class ELFT> void Writer<ELFT>:
   openFile(Config->OutputFile);
   writeHeader();
   writeSections();
-  error(Buffer->commit());
+  fatal(Buffer->commit());
 }
 
 namespace {
@@ -382,7 +382,7 @@ static void reportUndefined(SymbolTable<
   if (Config->NoInhibitExec)
     warning(Msg);
   else
-    error(Msg);
+    fatal(Msg);
 }
 
 template <class ELFT>
@@ -421,7 +421,7 @@ template <class ELFT> void Writer<ELFT>:
   for (const std::unique_ptr<ObjectFile<ELFT>> &F : Symtab.getObjectFiles()) {
     for (const Elf_Sym &Sym : F->getLocalSymbols()) {
       ErrorOr<StringRef> SymNameOrErr = Sym.getName(F->getStringTable());
-      error(SymNameOrErr);
+      fatal(SymNameOrErr);
       StringRef SymName = *SymNameOrErr;
       if (!shouldKeepInSymtab<ELFT>(*F, SymName, Sym))
         continue;
@@ -1318,7 +1318,7 @@ template <class ELFT> void Writer<ELFT>:
 template <class ELFT> void Writer<ELFT>::openFile(StringRef Path) {
   ErrorOr<std::unique_ptr<FileOutputBuffer>> BufferOrErr =
       FileOutputBuffer::create(Path, FileSize, FileOutputBuffer::F_executable);
-  error(BufferOrErr, "failed to open " + Path);
+  fatal(BufferOrErr, "failed to open " + Path);
   Buffer = std::move(*BufferOrErr);
 }
 

Modified: lld/trunk/include/lld/Driver/Driver.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Driver/Driver.h?rev=259069&r1=259068&r2=259069&view=diff
==============================================================================
--- lld/trunk/include/lld/Driver/Driver.h (original)
+++ lld/trunk/include/lld/Driver/Driver.h Thu Jan 28 12:40:06 2016
@@ -125,7 +125,7 @@ void link(llvm::ArrayRef<const char *> a
 }
 
 namespace elf2 {
-void link(llvm::ArrayRef<const char *> args);
+bool link(llvm::ArrayRef<const char *> args);
 }
 
 /// Driver for lld unit tests

Modified: lld/trunk/lib/Driver/UniversalDriver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Driver/UniversalDriver.cpp?rev=259069&r1=259068&r2=259069&view=diff
==============================================================================
--- lld/trunk/lib/Driver/UniversalDriver.cpp (original)
+++ lld/trunk/lib/Driver/UniversalDriver.cpp Thu Jan 28 12:40:06 2016
@@ -205,8 +205,7 @@ bool UniversalDriver::link(llvm::Mutable
   case Flavor::old_gnu_ld:
     return GnuLdDriver::linkELF(args, diagnostics);
   case Flavor::gnu_ld:
-    elf2::link(args);
-    return true;
+    return elf2::link(args);
   case Flavor::darwin_ld:
     return DarwinLdDriver::linkMachO(args, diagnostics);
   case Flavor::win_link:




More information about the llvm-commits mailing list