[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