[lld] 8b844de - [lld-link] Replace fatal(...) with Fatal

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Thu Dec 5 20:18:07 PST 2024


Author: Fangrui Song
Date: 2024-12-05T20:18:01-08:00
New Revision: 8b844de3c9c70f25bb79787158b8dc5b8fc11293

URL: https://github.com/llvm/llvm-project/commit/8b844de3c9c70f25bb79787158b8dc5b8fc11293
DIFF: https://github.com/llvm/llvm-project/commit/8b844de3c9c70f25bb79787158b8dc5b8fc11293.diff

LOG: [lld-link] Replace fatal(...) with Fatal

Added: 
    

Modified: 
    lld/COFF/DebugTypes.cpp
    lld/COFF/Driver.cpp
    lld/COFF/DriverUtils.cpp
    lld/COFF/InputFiles.cpp
    lld/COFF/InputFiles.h
    lld/COFF/MapFile.cpp
    lld/COFF/Writer.cpp

Removed: 
    


################################################################################
diff  --git a/lld/COFF/DebugTypes.cpp b/lld/COFF/DebugTypes.cpp
index 4d13d5d119addd..d4d80bfd92efbe 100644
--- a/lld/COFF/DebugTypes.cpp
+++ b/lld/COFF/DebugTypes.cpp
@@ -231,7 +231,7 @@ void TpiSource::remapRecord(MutableArrayRef<uint8_t> rec,
   for (const TiReference &ref : typeRefs) {
     unsigned byteSize = ref.Count * sizeof(TypeIndex);
     if (contents.size() < ref.Offset + byteSize)
-      fatal("symbol record too short");
+      Fatal(ctx) << "symbol record too short";
 
     MutableArrayRef<TypeIndex> indices(
         reinterpret_cast<TypeIndex *>(contents.data() + ref.Offset), ref.Count);
@@ -320,8 +320,8 @@ Error TpiSource::mergeDebugT(TypeMerger *m) {
   std::optional<PCHMergerInfo> pchInfo;
   if (auto err = mergeTypeAndIdRecords(m->idTable, m->typeTable,
                                        indexMapStorage, types, pchInfo))
-    fatal("codeview::mergeTypeAndIdRecords failed: " +
-          toString(std::move(err)));
+    Fatal(ctx) << "codeview::mergeTypeAndIdRecords failed: "
+               << toString(std::move(err));
   if (pchInfo) {
     file->pchSignature = pchInfo->PCHSignature;
     endPrecompIdx = pchInfo->EndPrecompIndex;
@@ -364,26 +364,30 @@ Error TypeServerSource::mergeDebugT(TypeMerger *m) {
   pdb::PDBFile &pdbFile = pdbInputFile->session->getPDBFile();
   Expected<pdb::TpiStream &> expectedTpi = pdbFile.getPDBTpiStream();
   if (auto e = expectedTpi.takeError())
-    fatal("Type server does not have TPI stream: " + toString(std::move(e)));
+    Fatal(ctx) << "Type server does not have TPI stream: "
+               << toString(std::move(e));
   pdb::TpiStream *maybeIpi = nullptr;
   if (pdbFile.hasPDBIpiStream()) {
     Expected<pdb::TpiStream &> expectedIpi = pdbFile.getPDBIpiStream();
     if (auto e = expectedIpi.takeError())
-      fatal("Error getting type server IPI stream: " + toString(std::move(e)));
+      Fatal(ctx) << "Error getting type server IPI stream: "
+                 << toString(std::move(e));
     maybeIpi = &*expectedIpi;
   }
 
   // Merge TPI first, because the IPI stream will reference type indices.
   if (auto err = mergeTypeRecords(m->typeTable, indexMapStorage,
                                   expectedTpi->typeArray()))
-    fatal("codeview::mergeTypeRecords failed: " + toString(std::move(err)));
+    Fatal(ctx) << "codeview::mergeTypeRecords failed: "
+               << toString(std::move(err));
   tpiMap = indexMapStorage;
 
   // Merge IPI.
   if (maybeIpi) {
     if (auto err = mergeIdRecords(m->idTable, tpiMap, ipiSrc->indexMapStorage,
                                   maybeIpi->typeArray()))
-      fatal("codeview::mergeIdRecords failed: " + toString(std::move(err)));
+      Fatal(ctx) << "codeview::mergeIdRecords failed: "
+                 << toString(std::move(err));
     ipiMap = ipiSrc->indexMapStorage;
   }
 
@@ -572,8 +576,10 @@ void PrecompSource::registerMapping() {
   if (file->pchSignature && *file->pchSignature) {
     auto it = ctx.precompSourceMappings.emplace(*file->pchSignature, this);
     if (!it.second)
-      fatal("a PCH object with the same signature has already been provided (" +
-            toString(it.first->second->file) + " and " + toString(file) + ")");
+      Fatal(ctx)
+          << "a PCH object with the same signature has already been provided ("
+          << toString(it.first->second->file) << " and " << toString(file)
+          << ")";
     registered = true;
   }
 }
@@ -756,7 +762,8 @@ void TypeServerSource::loadGHashes() {
   // Hash TPI stream.
   Expected<pdb::TpiStream &> expectedTpi = pdbFile.getPDBTpiStream();
   if (auto e = expectedTpi.takeError())
-    fatal("Type server does not have TPI stream: " + toString(std::move(e)));
+    Fatal(ctx) << "Type server does not have TPI stream: "
+               << toString(std::move(e));
   assignGHashesFromVector(
       GloballyHashedType::hashTypes(expectedTpi->typeArray()));
   isItemIndex.resize(ghashes.size());
@@ -766,7 +773,7 @@ void TypeServerSource::loadGHashes() {
     return;
   Expected<pdb::TpiStream &> expectedIpi = pdbFile.getPDBIpiStream();
   if (auto e = expectedIpi.takeError())
-    fatal("error retrieving IPI stream: " + toString(std::move(e)));
+    Fatal(ctx) << "error retrieving IPI stream: " << toString(std::move(e));
   ipiSrc->assignGHashesFromVector(
       GloballyHashedType::hashIds(expectedIpi->typeArray(), ghashes));
 

diff  --git a/lld/COFF/Driver.cpp b/lld/COFF/Driver.cpp
index 3c4fafff39e4fc..c1bf89ec0a5366 100644
--- a/lld/COFF/Driver.cpp
+++ b/lld/COFF/Driver.cpp
@@ -219,7 +219,7 @@ void LinkerDriver::addBuffer(std::unique_ptr<MemoryBuffer> mb,
       make<std::unique_ptr<Archive>>(std::move(file)); // take ownership
 
       int memberIndex = 0;
-      for (MemoryBufferRef m : getArchiveMembers(archive))
+      for (MemoryBufferRef m : getArchiveMembers(ctx, archive))
         addArchiveBuffer(m, "<whole-archive>", filename, memberIndex++);
       return;
     }
@@ -1033,8 +1033,8 @@ void LinkerDriver::createImportLibrary(bool asLib) {
   SmallString<128> tmpName;
   if (std::error_code ec =
           sys::fs::createUniqueFile(path + ".tmp-%%%%%%%%.lib", tmpName))
-    fatal("cannot create temporary file for import library " + path + ": " +
-          ec.message());
+    Fatal(ctx) << "cannot create temporary file for import library " << path
+               << ": " << ec.message();
 
   if (Error e = writeImportLibrary(libName, tmpName, exports,
                                    ctx.config.machine, ctx.config.mingw)) {
@@ -1233,11 +1233,11 @@ static void readCallGraphsFromObjectFiles(COFFLinkerContext &ctx) {
         uint32_t fromIndex, toIndex;
         uint64_t count;
         if (Error err = reader.readInteger(fromIndex))
-          fatal(toString(obj) + ": Expected 32-bit integer");
+          Fatal(ctx) << toString(obj) << ": Expected 32-bit integer";
         if (Error err = reader.readInteger(toIndex))
-          fatal(toString(obj) + ": Expected 32-bit integer");
+          Fatal(ctx) << toString(obj) << ": Expected 32-bit integer";
         if (Error err = reader.readInteger(count))
-          fatal(toString(obj) + ": Expected 64-bit integer");
+          Fatal(ctx) << toString(obj) << ": Expected 64-bit integer";
         auto *fromSym = dyn_cast_or_null<Defined>(obj->getSymbol(fromIndex));
         auto *toSym = dyn_cast_or_null<Defined>(obj->getSymbol(toIndex));
         if (!fromSym || !toSym)
@@ -1279,9 +1279,11 @@ static void findKeepUniqueSections(COFFLinkerContext &ctx) {
         const char *err = nullptr;
         uint64_t symIndex = decodeULEB128(cur, &size, contents.end(), &err);
         if (err)
-          fatal(toString(obj) + ": could not decode addrsig section: " + err);
+          Fatal(ctx) << toString(obj)
+                     << ": could not decode addrsig section: " << err;
         if (symIndex >= syms.size())
-          fatal(toString(obj) + ": invalid symbol index in addrsig section");
+          Fatal(ctx) << toString(obj)
+                     << ": invalid symbol index in addrsig section";
         markAddrsig(syms[symIndex]);
         cur += size;
       }
@@ -1574,7 +1576,7 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
       (StringRef(argsArr[1]).equals_insensitive("/lib") ||
        StringRef(argsArr[1]).equals_insensitive("-lib"))) {
     if (llvm::libDriverMain(argsArr.slice(1)) != 0)
-      fatal("lib failed");
+      Fatal(ctx) << "lib failed";
     return;
   }
 
@@ -1676,7 +1678,7 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
     if (args.hasArg(OPT_deffile))
       config->noEntry = true;
     else
-      fatal("no input files");
+      Fatal(ctx) << "no input files";
   }
 
   // Construct search path list.
@@ -1887,7 +1889,7 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
     if (auto *arg = args.getLastArg(OPT_machine)) {
       config->machine = getMachineType(arg->getValue());
       if (config->machine == IMAGE_FILE_MACHINE_UNKNOWN)
-        fatal(Twine("unknown /machine argument: ") + arg->getValue());
+        Fatal(ctx) << "unknown /machine argument: " << arg->getValue();
       addWinSysRootLibSearchPaths();
     }
   }
@@ -1955,8 +1957,8 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
       config->repro = false;
       StringRef value(arg->getValue());
       if (value.getAsInteger(0, config->timestamp))
-        fatal(Twine("invalid timestamp: ") + value +
-              ".  Expected 32-bit integer");
+        Fatal(ctx) << "invalid timestamp: " << value
+                   << ".  Expected 32-bit integer";
     }
   } else {
     config->repro = false;
@@ -1964,8 +1966,8 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
             Process::GetEnv("SOURCE_DATE_EPOCH")) {
       StringRef value(*epoch);
       if (value.getAsInteger(0, config->timestamp))
-        fatal(Twine("invalid SOURCE_DATE_EPOCH timestamp: ") + value +
-              ".  Expected 32-bit integer");
+        Fatal(ctx) << "invalid SOURCE_DATE_EPOCH timestamp: " << value
+                   << ".  Expected 32-bit integer";
     } else {
       config->timestamp = time(nullptr);
     }
@@ -2155,7 +2157,7 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
 
   if (!config->manifestInput.empty() &&
       config->manifest != Configuration::Embed) {
-    fatal("/manifestinput: requires /manifest:embed");
+    Fatal(ctx) << "/manifestinput: requires /manifest:embed";
   }
 
   // Handle /dwodir
@@ -2400,7 +2402,7 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
     llvm::TimeTraceScope timeScope("Infer subsystem");
     config->subsystem = inferSubsystem();
     if (config->subsystem == IMAGE_SUBSYSTEM_UNKNOWN)
-      fatal("subsystem must be defined");
+      Fatal(ctx) << "subsystem must be defined";
   }
 
   // Handle /entry and /dll
@@ -2408,7 +2410,7 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
     llvm::TimeTraceScope timeScope("Entry point");
     if (auto *arg = args.getLastArg(OPT_entry)) {
       if (!arg->getValue()[0])
-        fatal("missing entry point symbol name");
+        Fatal(ctx) << "missing entry point symbol name";
       config->entry = addUndefined(mangle(arg->getValue()), true);
     } else if (!config->entry && !config->noEntry) {
       if (args.hasArg(OPT_dll)) {
@@ -2423,7 +2425,7 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
         // infer that from user-defined entry name.
         StringRef s = findDefaultEntry();
         if (s.empty())
-          fatal("entry point must be defined");
+          Fatal(ctx) << "entry point must be defined";
         config->entry = addUndefined(s, true);
         Log(ctx) << "Entry name inferred: " << s;
       }

diff  --git a/lld/COFF/DriverUtils.cpp b/lld/COFF/DriverUtils.cpp
index bec8f6940c9a72..44c8349079cc5e 100644
--- a/lld/COFF/DriverUtils.cpp
+++ b/lld/COFF/DriverUtils.cpp
@@ -83,9 +83,9 @@ class Executor {
 void LinkerDriver::parseNumbers(StringRef arg, uint64_t *addr, uint64_t *size) {
   auto [s1, s2] = arg.split(',');
   if (s1.getAsInteger(0, *addr))
-    fatal("invalid number: " + s1);
+    Fatal(ctx) << "invalid number: " << s1;
   if (size && !s2.empty() && s2.getAsInteger(0, *size))
-    fatal("invalid number: " + s2);
+    Fatal(ctx) << "invalid number: " << s2;
 }
 
 // Parses a string in the form of "<integer>[.<integer>]".
@@ -94,10 +94,10 @@ void LinkerDriver::parseVersion(StringRef arg, uint32_t *major,
                                 uint32_t *minor) {
   auto [s1, s2] = arg.split('.');
   if (s1.getAsInteger(10, *major))
-    fatal("invalid number: " + s1);
+    Fatal(ctx) << "invalid number: " << s1;
   *minor = 0;
   if (!s2.empty() && s2.getAsInteger(10, *minor))
-    fatal("invalid number: " + s2);
+    Fatal(ctx) << "invalid number: " << s2;
 }
 
 void LinkerDriver::parseGuard(StringRef fullArg) {
@@ -115,7 +115,7 @@ void LinkerDriver::parseGuard(StringRef fullArg) {
     else if (arg.equals_insensitive("ehcont"))
       ctx.config.guardCF |= GuardCFLevel::CF | GuardCFLevel::EHCont;
     else
-      fatal("invalid argument to /guard: " + arg);
+      Fatal(ctx) << "invalid argument to /guard: " << arg;
   }
 }
 
@@ -138,7 +138,7 @@ void LinkerDriver::parseSubsystem(StringRef arg, WindowsSubsystem *sys,
     .Case("windows", IMAGE_SUBSYSTEM_WINDOWS_GUI)
     .Default(IMAGE_SUBSYSTEM_UNKNOWN);
   if (*sys == IMAGE_SUBSYSTEM_UNKNOWN && sysStrLower != "default")
-    fatal("unknown subsystem: " + sysStr);
+    Fatal(ctx) << "unknown subsystem: " << sysStr;
   if (!ver.empty())
     parseVersion(ver, major, minor);
   if (gotVersion)
@@ -150,10 +150,10 @@ void LinkerDriver::parseSubsystem(StringRef arg, WindowsSubsystem *sys,
 void LinkerDriver::parseAlternateName(StringRef s) {
   auto [from, to] = s.split('=');
   if (from.empty() || to.empty())
-    fatal("/alternatename: invalid argument: " + s);
+    Fatal(ctx) << "/alternatename: invalid argument: " << s;
   auto it = ctx.config.alternateNames.find(from);
   if (it != ctx.config.alternateNames.end() && it->second != to)
-    fatal("/alternatename: conflicts: " + s);
+    Fatal(ctx) << "/alternatename: conflicts: " << s;
   ctx.config.alternateNames.insert(it, std::make_pair(from, to));
 }
 
@@ -162,11 +162,11 @@ void LinkerDriver::parseAlternateName(StringRef s) {
 void LinkerDriver::parseMerge(StringRef s) {
   auto [from, to] = s.split('=');
   if (from.empty() || to.empty())
-    fatal("/merge: invalid argument: " + s);
+    Fatal(ctx) << "/merge: invalid argument: " << s;
   if (from == ".rsrc" || to == ".rsrc")
-    fatal("/merge: cannot merge '.rsrc' with any section");
+    Fatal(ctx) << "/merge: cannot merge '.rsrc' with any section";
   if (from == ".reloc" || to == ".reloc")
-    fatal("/merge: cannot merge '.reloc' with any section");
+    Fatal(ctx) << "/merge: cannot merge '.reloc' with any section";
   auto pair = ctx.config.merge.insert(std::make_pair(from, to));
   bool inserted = pair.second;
   if (!inserted) {
@@ -190,7 +190,7 @@ void LinkerDriver::parsePDBPageSize(StringRef s) {
   ctx.config.pdbPageSize = v;
 }
 
-static uint32_t parseSectionAttributes(StringRef s) {
+static uint32_t parseSectionAttributes(COFFLinkerContext &ctx, StringRef s) {
   uint32_t ret = 0;
   for (char c : s.lower()) {
     switch (c) {
@@ -216,7 +216,7 @@ static uint32_t parseSectionAttributes(StringRef s) {
       ret |= IMAGE_SCN_MEM_WRITE;
       break;
     default:
-      fatal("/section: invalid argument: " + s);
+      Fatal(ctx) << "/section: invalid argument: " << s;
     }
   }
   return ret;
@@ -226,8 +226,8 @@ static uint32_t parseSectionAttributes(StringRef s) {
 void LinkerDriver::parseSection(StringRef s) {
   auto [name, attrs] = s.split(',');
   if (name.empty() || attrs.empty())
-    fatal("/section: invalid argument: " + s);
-  ctx.config.section[name] = parseSectionAttributes(attrs);
+    Fatal(ctx) << "/section: invalid argument: " << s;
+  ctx.config.section[name] = parseSectionAttributes(ctx, attrs);
 }
 
 // Parses /aligncomm option argument.
@@ -289,16 +289,16 @@ void LinkerDriver::parseManifest(StringRef arg) {
     return;
   }
   if (!arg.starts_with_insensitive("embed"))
-    fatal("invalid option " + arg);
+    Fatal(ctx) << "invalid option " << arg;
   ctx.config.manifest = Configuration::Embed;
   arg = arg.substr(strlen("embed"));
   if (arg.empty())
     return;
   if (!arg.starts_with_insensitive(",id="))
-    fatal("invalid option " + arg);
+    Fatal(ctx) << "invalid option " << arg;
   arg = arg.substr(strlen(",id="));
   if (arg.getAsInteger(0, ctx.config.manifestID))
-    fatal("invalid option " + arg);
+    Fatal(ctx) << "invalid option " << arg;
 }
 
 // Parses a string in the form of "level=<string>|uiAccess=<string>|NO".
@@ -320,7 +320,7 @@ void LinkerDriver::parseManifestUAC(StringRef arg) {
       std::tie(ctx.config.manifestUIAccess, arg) = arg.split(" ");
       continue;
     }
-    fatal("invalid option " + arg);
+    Fatal(ctx) << "invalid option " << arg;
   }
 }
 
@@ -348,28 +348,32 @@ void LinkerDriver::parseSwaprun(StringRef arg) {
 namespace {
 class TemporaryFile {
 public:
-  TemporaryFile(StringRef prefix, StringRef extn, StringRef contents = "") {
+  TemporaryFile(COFFLinkerContext &ctx, StringRef prefix, StringRef extn,
+                StringRef contents = "")
+      : ctx(ctx) {
     SmallString<128> s;
     if (auto ec = sys::fs::createTemporaryFile("lld-" + prefix, extn, s))
-      fatal("cannot create a temporary file: " + ec.message());
+      Fatal(ctx) << "cannot create a temporary file: " << ec.message();
     path = std::string(s);
 
     if (!contents.empty()) {
       std::error_code ec;
       raw_fd_ostream os(path, ec, sys::fs::OF_None);
       if (ec)
-        fatal("failed to open " + path + ": " + ec.message());
+        Fatal(ctx) << "failed to open " << path << ": " << ec.message();
       os << contents;
     }
   }
 
-  TemporaryFile(TemporaryFile &&obj) noexcept { std::swap(path, obj.path); }
+  TemporaryFile(TemporaryFile &&obj) noexcept : ctx(obj.ctx) {
+    std::swap(path, obj.path);
+  }
 
   ~TemporaryFile() {
     if (path.empty())
       return;
     if (sys::fs::remove(path))
-      fatal("failed to remove " + path);
+      Fatal(ctx) << "failed to remove " << path;
   }
 
   // Returns a memory buffer of this temporary file.
@@ -384,6 +388,7 @@ class TemporaryFile {
                  "could not open " + path);
   }
 
+  COFFLinkerContext &ctx;
   std::string path;
 };
 }
@@ -425,16 +430,16 @@ LinkerDriver::createManifestXmlWithInternalMt(StringRef defaultXml) {
 
   windows_manifest::WindowsManifestMerger merger;
   if (auto e = merger.merge(*defaultXmlCopy.get()))
-    fatal("internal manifest tool failed on default xml: " +
-          toString(std::move(e)));
+    Fatal(ctx) << "internal manifest tool failed on default xml: "
+               << toString(std::move(e));
 
   for (StringRef filename : ctx.config.manifestInput) {
     std::unique_ptr<MemoryBuffer> manifest =
         check(MemoryBuffer::getFile(filename));
     // Call takeBuffer to include in /reproduce: output if applicable.
     if (auto e = merger.merge(takeBuffer(std::move(manifest))))
-      fatal("internal manifest tool failed on file " + filename + ": " +
-            toString(std::move(e)));
+      Fatal(ctx) << "internal manifest tool failed on file " << filename << ": "
+                 << toString(std::move(e));
   }
 
   return std::string(merger.getMergedManifest().get()->getBuffer());
@@ -443,17 +448,17 @@ LinkerDriver::createManifestXmlWithInternalMt(StringRef defaultXml) {
 std::string
 LinkerDriver::createManifestXmlWithExternalMt(StringRef defaultXml) {
   // Create the default manifest file as a temporary file.
-  TemporaryFile Default("defaultxml", "manifest");
+  TemporaryFile Default(ctx, "defaultxml", "manifest");
   std::error_code ec;
   raw_fd_ostream os(Default.path, ec, sys::fs::OF_TextWithCRLF);
   if (ec)
-    fatal("failed to open " + Default.path + ": " + ec.message());
+    Fatal(ctx) << "failed to open " << Default.path << ": " << ec.message();
   os << defaultXml;
   os.close();
 
   // Merge user-supplied manifests if they are given.  Since libxml2 is not
   // enabled, we must shell out to Microsoft's mt.exe tool.
-  TemporaryFile user("user", "manifest");
+  TemporaryFile user(ctx, "user", "manifest");
 
   Executor e("mt.exe");
   e.add("/manifest");
@@ -555,7 +560,7 @@ void LinkerDriver::createSideBySideManifest() {
   std::error_code ec;
   raw_fd_ostream out(path, ec, sys::fs::OF_TextWithCRLF);
   if (ec)
-    fatal("failed to create manifest: " + ec.message());
+    Fatal(ctx) << "failed to create manifest: " << ec.message();
   out << createManifestXml();
 }
 
@@ -631,7 +636,8 @@ Export LinkerDriver::parseExport(StringRef arg) {
   return e;
 
 err:
-  fatal("invalid /export: " + arg);
+  Fatal(ctx) << "invalid /export: " << arg;
+  llvm_unreachable("");
 }
 
 // Convert stdcall/fastcall style symbols into unsuffixed symbols,
@@ -677,7 +683,7 @@ void LinkerDriver::fixupExports() {
     if (e.ordinal == 0)
       continue;
     if (!ords.insert(e.ordinal).second)
-      fatal("duplicate export ordinal: " + e.name);
+      Fatal(ctx) << "duplicate export ordinal: " << e.name;
   }
 
   for (Export &e : ctx.config.exports) {
@@ -766,8 +772,8 @@ void LinkerDriver::assignExportOrdinals() {
     if (e.ordinal == 0)
       e.ordinal = ++max;
   if (max > std::numeric_limits<uint16_t>::max())
-    fatal("too many exported symbols (got " + Twine(max) + ", max " +
-          Twine(std::numeric_limits<uint16_t>::max()) + ")");
+    Fatal(ctx) << "too many exported symbols (got " << max << ", max "
+               << Twine(std::numeric_limits<uint16_t>::max()) << ")";
 }
 
 // Parses a string in the form of "key=value" and check
@@ -775,15 +781,15 @@ void LinkerDriver::assignExportOrdinals() {
 void LinkerDriver::checkFailIfMismatch(StringRef arg, InputFile *source) {
   auto [k, v] = arg.split('=');
   if (k.empty() || v.empty())
-    fatal("/failifmismatch: invalid argument: " + arg);
+    Fatal(ctx) << "/failifmismatch: invalid argument: " << arg;
   std::pair<StringRef, InputFile *> existing = ctx.config.mustMatch[k];
   if (!existing.first.empty() && v != existing.first) {
     std::string sourceStr = source ? toString(source) : "cmd-line";
     std::string existingStr =
         existing.second ? toString(existing.second) : "cmd-line";
-    fatal("/failifmismatch: mismatch detected for '" + k + "':\n>>> " +
-          existingStr + " has value " + existing.first + "\n>>> " + sourceStr +
-          " has value " + v);
+    Fatal(ctx) << "/failifmismatch: mismatch detected for '" << k << "':\n>>> "
+               << existingStr << " has value " << existing.first << "\n>>> "
+               << sourceStr << " has value " << v;
   }
   ctx.config.mustMatch[k] = {v, source};
 }
@@ -799,10 +805,10 @@ MemoryBufferRef LinkerDriver::convertResToCOFF(ArrayRef<MemoryBufferRef> mbs,
     std::unique_ptr<object::Binary> bin = check(object::createBinary(mb));
     object::WindowsResource *rf = dyn_cast<object::WindowsResource>(bin.get());
     if (!rf)
-      fatal("cannot compile non-resource file as resource");
+      Fatal(ctx) << "cannot compile non-resource file as resource";
 
     if (auto ec = parser.parse(rf, duplicates))
-      fatal(toString(std::move(ec)));
+      Fatal(ctx) << toString(std::move(ec));
   }
 
   // Note: This processes all .res files before all objs. Ideally they'd be
@@ -811,10 +817,10 @@ MemoryBufferRef LinkerDriver::convertResToCOFF(ArrayRef<MemoryBufferRef> mbs,
   for (ObjFile *f : objs) {
     object::ResourceSectionRef rsf;
     if (auto ec = rsf.load(f->getCOFFObj()))
-      fatal(toString(f) + ": " + toString(std::move(ec)));
+      Fatal(ctx) << toString(f) << ": " << toString(std::move(ec));
 
     if (auto ec = parser.parse(rsf, f->getName(), duplicates))
-      fatal(toString(std::move(ec)));
+      Fatal(ctx) << toString(std::move(ec));
   }
 
   if (ctx.config.mingw)
@@ -830,7 +836,7 @@ MemoryBufferRef LinkerDriver::convertResToCOFF(ArrayRef<MemoryBufferRef> mbs,
       llvm::object::writeWindowsResourceCOFF(ctx.config.machine, parser,
                                              ctx.config.timestamp);
   if (!e)
-    fatal("failed to write .res to COFF: " + toString(e.takeError()));
+    Fatal(ctx) << "failed to write .res to COFF: " << toString(e.takeError());
 
   MemoryBufferRef mbref = **e;
   make<std::unique_ptr<MemoryBuffer>>(std::move(*e)); // take ownership
@@ -938,7 +944,7 @@ opt::InputArgList ArgParser::parse(ArrayRef<const char *> argv) {
   ctx.e.fatalWarnings = args.hasFlag(OPT_WX, OPT_WX_no, false);
 
   if (missingCount)
-    fatal(Twine(args.getArgString(missingIndex)) + ": missing argument");
+    Fatal(ctx) << args.getArgString(missingIndex) << ": missing argument";
 
   handleColorDiagnostics(ctx, args);
 
@@ -993,7 +999,8 @@ ParsedDirectives ArgParser::parseDirectives(StringRef s) {
   result.args = ctx.optTable.ParseArgs(rest, missingIndex, missingCount);
 
   if (missingCount)
-    fatal(Twine(result.args.getArgString(missingIndex)) + ": missing argument");
+    Fatal(ctx) << result.args.getArgString(missingIndex)
+               << ": missing argument";
   for (auto *arg : result.args.filtered(OPT_UNKNOWN))
     Warn(ctx) << "ignoring unknown argument: " << arg->getAsString(result.args);
   return result;

diff  --git a/lld/COFF/InputFiles.cpp b/lld/COFF/InputFiles.cpp
index 1e3f11c0fbaf68..207fa40f2904d1 100644
--- a/lld/COFF/InputFiles.cpp
+++ b/lld/COFF/InputFiles.cpp
@@ -144,7 +144,8 @@ void ArchiveFile::addMember(const Archive::Symbol &sym) {
   ctx.driver.enqueueArchiveMember(c, sym, getName());
 }
 
-std::vector<MemoryBufferRef> lld::coff::getArchiveMembers(Archive *file) {
+std::vector<MemoryBufferRef>
+lld::coff::getArchiveMembers(COFFLinkerContext &ctx, Archive *file) {
   std::vector<MemoryBufferRef> v;
   Error err = Error::success();
   for (const Archive::Child &c : file->children(err)) {
@@ -155,8 +156,8 @@ std::vector<MemoryBufferRef> lld::coff::getArchiveMembers(Archive *file) {
     v.push_back(mbref);
   }
   if (err)
-    fatal(file->getFileName() +
-          ": Archive::children failed: " + toString(std::move(err)));
+    Fatal(ctx) << file->getFileName()
+               << ": Archive::children failed: " << toString(std::move(err));
   return v;
 }
 
@@ -220,7 +221,7 @@ void ObjFile::parse() {
     bin.release();
     coffObj.reset(obj);
   } else {
-    fatal(toString(this) + " is not a COFF file");
+    Fatal(ctx) << toString(this) << " is not a COFF file";
   }
 
   // Read section and symbol tables.
@@ -234,7 +235,7 @@ void ObjFile::parse() {
 const coff_section *ObjFile::getSection(uint32_t i) {
   auto sec = coffObj->getSection(i);
   if (!sec)
-    fatal("getSection failed: #" + Twine(i) + ": " + toString(sec.takeError()));
+    Fatal(ctx) << "getSection failed: #" << i << ": " << sec.takeError();
   return *sec;
 }
 
@@ -267,8 +268,8 @@ SectionChunk *ObjFile::readSection(uint32_t sectionNumber,
   if (Expected<StringRef> e = coffObj->getSectionName(sec))
     name = *e;
   else
-    fatal("getSectionName failed: #" + Twine(sectionNumber) + ": " +
-          toString(e.takeError()));
+    Fatal(ctx) << "getSectionName failed: #" << sectionNumber << ": "
+               << e.takeError();
 
   if (name == ".drectve") {
     ArrayRef<uint8_t> data;
@@ -723,12 +724,14 @@ std::optional<Symbol *> ObjFile::createDefined(
     return nullptr;
 
   if (llvm::COFF::isReservedSectionNumber(sectionNumber))
-    fatal(toString(this) + ": " + getName() +
-          " should not refer to special section " + Twine(sectionNumber));
+    Fatal(ctx) << toString(this) << ": " << getName()
+               << " should not refer to special section "
+               << Twine(sectionNumber);
 
   if ((uint32_t)sectionNumber >= sparseChunks.size())
-    fatal(toString(this) + ": " + getName() +
-          " should not refer to non-existent section " + Twine(sectionNumber));
+    Fatal(ctx) << toString(this) << ": " << getName()
+               << " should not refer to non-existent section "
+               << Twine(sectionNumber);
 
   // Comdat handling.
   // A comdat symbol consists of two symbol table entries.
@@ -758,8 +761,9 @@ std::optional<Symbol *> ObjFile::createDefined(
         // Intentionally ends at IMAGE_COMDAT_SELECT_LARGEST: link.exe
         // doesn't understand IMAGE_COMDAT_SELECT_NEWEST either.
         def->Selection > (int)IMAGE_COMDAT_SELECT_LARGEST) {
-      fatal("unknown comdat type " + std::to_string((int)def->Selection) +
-            " for " + getName() + " in " + toString(this));
+      Fatal(ctx) << "unknown comdat type "
+                 << std::to_string((int)def->Selection) << " for " << getName()
+                 << " in " << toString(this);
     }
     COMDATType selection = (COMDATType)def->Selection;
 
@@ -1084,7 +1088,7 @@ void ImportFile::parse() {
   // Check if the total size is valid.
   if (mb.getBufferSize() < sizeof(*hdr) ||
       mb.getBufferSize() != sizeof(*hdr) + hdr->SizeOfData)
-    fatal("broken import library");
+    Fatal(ctx) << "broken import library";
 
   // Read names and create an __imp_ symbol.
   StringRef buf = mb.getBuffer().substr(sizeof(*hdr));

diff  --git a/lld/COFF/InputFiles.h b/lld/COFF/InputFiles.h
index e727d1376e2f2d..3c48e778ac5b5d 100644
--- a/lld/COFF/InputFiles.h
+++ b/lld/COFF/InputFiles.h
@@ -42,7 +42,8 @@ class COFFLinkerContext;
 
 const COFFSyncStream &operator<<(const COFFSyncStream &, const InputFile *);
 
-std::vector<MemoryBufferRef> getArchiveMembers(llvm::object::Archive *file);
+std::vector<MemoryBufferRef> getArchiveMembers(COFFLinkerContext &,
+                                               llvm::object::Archive *file);
 
 using llvm::COFF::IMAGE_FILE_MACHINE_UNKNOWN;
 using llvm::COFF::MachineTypes;

diff  --git a/lld/COFF/MapFile.cpp b/lld/COFF/MapFile.cpp
index 55a1cd942ab858..e3531c04e77473 100644
--- a/lld/COFF/MapFile.cpp
+++ b/lld/COFF/MapFile.cpp
@@ -209,7 +209,7 @@ void lld::coff::writeMapFile(COFFLinkerContext &ctx) {
   std::error_code ec;
   raw_fd_ostream os(ctx.config.mapFile, ec, sys::fs::OF_None);
   if (ec)
-    fatal("cannot open " + ctx.config.mapFile + ": " + ec.message());
+    Fatal(ctx) << "cannot open " << ctx.config.mapFile << ": " << ec.message();
 
   ScopedTimer t1(ctx.totalMapTimer);
 

diff  --git a/lld/COFF/Writer.cpp b/lld/COFF/Writer.cpp
index 129cce83b6b85f..ed70365f7ccbcc 100644
--- a/lld/COFF/Writer.cpp
+++ b/lld/COFF/Writer.cpp
@@ -682,7 +682,8 @@ void Writer::finalizeAddresses() {
     }
 
     if (pass >= 10)
-      fatal("adding thunks hasn't converged after " + Twine(pass) + " passes");
+      Fatal(ctx) << "adding thunks hasn't converged after " << pass
+                 << " passes";
 
     if (pass > 0) {
       // If the previous pass didn't work out, reset everything back to the
@@ -781,8 +782,8 @@ void Writer::run() {
     createSymbolAndStringTable();
 
     if (fileSize > UINT32_MAX)
-      fatal("image size (" + Twine(fileSize) + ") " +
-            "exceeds maximum allowable size (" + Twine(UINT32_MAX) + ")");
+      Fatal(ctx) << "image size (" << fileSize << ") "
+                 << "exceeds maximum allowable size (" << UINT32_MAX << ")";
 
     openFile(ctx.config.outputFile);
     if (ctx.config.is64()) {
@@ -817,8 +818,8 @@ void Writer::run() {
   llvm::TimeTraceScope timeScope("Commit PE to disk");
   ScopedTimer t2(ctx.outputCommitTimer);
   if (auto e = buffer->commit())
-    fatal("failed to write output '" + buffer->getPath() +
-          "': " + toString(std::move(e)));
+    Fatal(ctx) << "failed to write output '" << buffer->getPath()
+               << "': " << toString(std::move(e));
 }
 
 static StringRef getOutputSectionName(StringRef name) {
@@ -1255,12 +1256,12 @@ void Writer::createImportTables() {
       ctx.config.dllOrder[dll] = ctx.config.dllOrder.size();
 
     if (file->impSym && !isa<DefinedImportData>(file->impSym))
-      fatal(toString(ctx, *file->impSym) + " was replaced");
+      Fatal(ctx) << toString(ctx, *file->impSym) << " was replaced";
     DefinedImportData *impSym = cast_or_null<DefinedImportData>(file->impSym);
     if (ctx.config.delayLoads.count(StringRef(file->dllName).lower())) {
       if (!file->thunkSym)
-        fatal("cannot delay-load " + toString(file) +
-              " due to import of data: " + toString(ctx, *impSym));
+        Fatal(ctx) << "cannot delay-load " << toString(file)
+                   << " due to import of data: " << toString(ctx, *impSym);
       delayIdata.add(impSym);
     } else {
       idata.add(impSym);
@@ -1279,7 +1280,7 @@ void Writer::appendImportThunks() {
 
     if (file->thunkSym) {
       if (!isa<DefinedImportThunk>(file->thunkSym))
-        fatal(toString(ctx, *file->thunkSym) + " was replaced");
+        Fatal(ctx) << toString(ctx, *file->thunkSym) << " was replaced";
       auto *chunk = cast<DefinedImportThunk>(file->thunkSym)->getChunk();
       if (chunk->live)
         textSec->addChunk(chunk);
@@ -1287,7 +1288,7 @@ void Writer::appendImportThunks() {
 
     if (file->auxThunkSym) {
       if (!isa<DefinedImportThunk>(file->auxThunkSym))
-        fatal(toString(ctx, *file->auxThunkSym) + " was replaced");
+        Fatal(ctx) << toString(ctx, *file->auxThunkSym) << " was replaced";
       auto *chunk = cast<DefinedImportThunk>(file->auxThunkSym)->getChunk();
       if (chunk->live)
         textSec->addChunk(chunk);
@@ -1547,7 +1548,7 @@ void Writer::mergeSections() {
     StringSet<> names;
     while (true) {
       if (!names.insert(toName).second)
-        fatal("/merge: cycle found for section '" + p.first + "'");
+        Fatal(ctx) << "/merge: cycle found for section '" << p.first << "'";
       auto i = ctx.config.merge.find(toName);
       if (i == ctx.config.merge.end())
         break;
@@ -1842,13 +1843,13 @@ template <typename PEHeaderTy> void Writer::writeHeader() {
       assert(b->getRVA() >= sc->getRVA());
       uint64_t offsetInChunk = b->getRVA() - sc->getRVA();
       if (!sc->hasData || offsetInChunk + 4 > sc->getSize())
-        fatal("_load_config_used is malformed");
+        Fatal(ctx) << "_load_config_used is malformed";
 
       ArrayRef<uint8_t> secContents = sc->getContents();
       uint32_t loadConfigSize =
           *reinterpret_cast<const ulittle32_t *>(&secContents[offsetInChunk]);
       if (offsetInChunk + loadConfigSize > sc->getSize())
-        fatal("_load_config_used is too large");
+        Fatal(ctx) << "_load_config_used is too large";
       dir[LOAD_CONFIG_TABLE].RelativeVirtualAddress = b->getRVA();
       dir[LOAD_CONFIG_TABLE].Size = loadConfigSize;
     }
@@ -2451,8 +2452,8 @@ void Writer::sortExceptionTable(ChunkRange &exceptionTable) {
   uint8_t *begin = bufAddr(exceptionTable.first);
   uint8_t *end = bufAddr(exceptionTable.last) + exceptionTable.last->getSize();
   if ((end - begin) % sizeof(T) != 0) {
-    fatal("unexpected .pdata size: " + Twine(end - begin) +
-          " is not a multiple of " + Twine(sizeof(T)));
+    Fatal(ctx) << "unexpected .pdata size: " << (end - begin)
+               << " is not a multiple of " << sizeof(T);
   }
 
   parallelSort(MutableArrayRef<T>(reinterpret_cast<T *>(begin),
@@ -2634,7 +2635,7 @@ void Writer::fixTlsAlignment() {
                                : sizeof(object::coff_tls_directory32);
 
   if (tlsOffset + directorySize > sec->getRawSize())
-    fatal("_tls_used sym is malformed");
+    Fatal(ctx) << "_tls_used sym is malformed";
 
   if (ctx.config.is64()) {
     object::coff_tls_directory64 *tlsDir =


        


More information about the llvm-commits mailing list