[lld] 09c2c5e - [ELF] Replace error(...) with ErrAlways or Err
Fangrui Song via llvm-commits
llvm-commits at lists.llvm.org
Wed Nov 6 22:04:58 PST 2024
Author: Fangrui Song
Date: 2024-11-06T22:04:52-08:00
New Revision: 09c2c5e1e9f3b3bb17f777f153407430f3cef15e
URL: https://github.com/llvm/llvm-project/commit/09c2c5e1e9f3b3bb17f777f153407430f3cef15e
DIFF: https://github.com/llvm/llvm-project/commit/09c2c5e1e9f3b3bb17f777f153407430f3cef15e.diff
LOG: [ELF] Replace error(...) with ErrAlways or Err
Most are migrated to ErrAlways mechanically.
In the future we should change most to Err.
Added:
Modified:
lld/ELF/Arch/AArch64.cpp
lld/ELF/Arch/AMDGPU.cpp
lld/ELF/Arch/ARM.cpp
lld/ELF/Arch/AVR.cpp
lld/ELF/Arch/Hexagon.cpp
lld/ELF/Arch/LoongArch.cpp
lld/ELF/Arch/MSP430.cpp
lld/ELF/Arch/Mips.cpp
lld/ELF/Arch/MipsArchTree.cpp
lld/ELF/Arch/PPC.cpp
lld/ELF/Arch/PPC64.cpp
lld/ELF/Arch/RISCV.cpp
lld/ELF/Arch/SPARCV9.cpp
lld/ELF/Arch/SystemZ.cpp
lld/ELF/Arch/X86.cpp
lld/ELF/Arch/X86_64.cpp
lld/ELF/CallGraphSort.cpp
lld/ELF/Config.h
lld/ELF/Driver.cpp
lld/ELF/DriverUtils.cpp
lld/ELF/InputFiles.cpp
lld/ELF/InputSection.cpp
lld/ELF/LTO.cpp
lld/ELF/LinkerScript.cpp
lld/ELF/MapFile.cpp
lld/ELF/OutputSections.cpp
lld/ELF/Relocations.cpp
lld/ELF/ScriptLexer.cpp
lld/ELF/ScriptParser.cpp
lld/ELF/Symbols.cpp
lld/ELF/SyntheticSections.cpp
lld/ELF/Writer.cpp
Removed:
################################################################################
diff --git a/lld/ELF/Arch/AArch64.cpp b/lld/ELF/Arch/AArch64.cpp
index 28e0fce6a6f499..025672d4a3665d 100644
--- a/lld/ELF/Arch/AArch64.cpp
+++ b/lld/ELF/Arch/AArch64.cpp
@@ -213,8 +213,8 @@ RelExpr AArch64::getRelExpr(RelType type, const Symbol &s,
case R_AARCH64_NONE:
return R_NONE;
default:
- error(getErrorLoc(ctx, loc) + "unknown relocation (" + Twine(type) +
- ") against symbol " + toString(s));
+ Err(ctx) << getErrorLoc(ctx, loc) << "unknown relocation (" << Twine(type)
+ << ") against symbol " << &s;
return R_NONE;
}
}
@@ -1113,7 +1113,8 @@ addTaggedSymbolReferences(InputSectionBase &sec,
const RelsOrRelas<ELFT> rels = sec.relsOrRelas<ELFT>();
if (rels.areRelocsRel())
- error("non-RELA relocations are not allowed with memtag globals");
+ ErrAlways(ctx)
+ << "non-RELA relocations are not allowed with memtag globals";
for (const typename ELFT::Rela &rel : rels.relas) {
Symbol &sym = sec.file->getRelocTargetSym(rel);
@@ -1196,7 +1197,7 @@ void elf::createTaggedSymbols(Ctx &ctx) {
// relocations, the only other way to get written addends is with
// --apply-dynamic-relocs.
if (!taggedSymbolReferenceCount.empty() && ctx.arg.writeAddends)
- error("--apply-dynamic-relocs cannot be used with MTE globals");
+ ErrAlways(ctx) << "--apply-dynamic-relocs cannot be used with MTE globals";
// Now, `taggedSymbolReferenceCount` should only contain symbols that are
// defined as tagged exactly the same amount as it's referenced, meaning all
diff --git a/lld/ELF/Arch/AMDGPU.cpp b/lld/ELF/Arch/AMDGPU.cpp
index b4bb029feb72ab..fb567085de3719 100644
--- a/lld/ELF/Arch/AMDGPU.cpp
+++ b/lld/ELF/Arch/AMDGPU.cpp
@@ -56,7 +56,7 @@ uint32_t AMDGPU::calcEFlagsV3() const {
for (InputFile *f : ArrayRef(ctx.objectFiles).slice(1)) {
if (ret == getEFlags(f))
continue;
- error("incompatible e_flags: " + toString(f));
+ ErrAlways(ctx) << "incompatible e_flags: " << f;
return 0;
}
return ret;
@@ -73,7 +73,7 @@ uint32_t AMDGPU::calcEFlagsV4() const {
// features in the same category are either ANY, ANY and ON, or ANY and OFF).
for (InputFile *f : ArrayRef(ctx.objectFiles).slice(1)) {
if (retMach != (getEFlags(f) & EF_AMDGPU_MACH)) {
- error("incompatible mach: " + toString(f));
+ ErrAlways(ctx) << "incompatible mach: " << f;
return 0;
}
@@ -82,7 +82,7 @@ uint32_t AMDGPU::calcEFlagsV4() const {
(getEFlags(f) & EF_AMDGPU_FEATURE_XNACK_V4)
!= EF_AMDGPU_FEATURE_XNACK_ANY_V4)) {
if (retXnack != (getEFlags(f) & EF_AMDGPU_FEATURE_XNACK_V4)) {
- error("incompatible xnack: " + toString(f));
+ ErrAlways(ctx) << "incompatible xnack: " << f;
return 0;
}
} else {
@@ -95,7 +95,7 @@ uint32_t AMDGPU::calcEFlagsV4() const {
(getEFlags(f) & EF_AMDGPU_FEATURE_SRAMECC_V4) !=
EF_AMDGPU_FEATURE_SRAMECC_ANY_V4)) {
if (retSramEcc != (getEFlags(f) & EF_AMDGPU_FEATURE_SRAMECC_V4)) {
- error("incompatible sramecc: " + toString(f));
+ ErrAlways(ctx) << "incompatible sramecc: " << f;
return 0;
}
} else {
@@ -116,7 +116,7 @@ uint32_t AMDGPU::calcEFlagsV6() const {
// Verify that all input files have compatible generic version.
for (InputFile *f : ArrayRef(ctx.objectFiles).slice(1)) {
if (genericVersion != (getEFlags(f) & EF_AMDGPU_GENERIC_VERSION)) {
- error("incompatible generic version: " + toString(f));
+ ErrAlways(ctx) << "incompatible generic version: " << f;
return 0;
}
}
@@ -143,7 +143,7 @@ uint32_t AMDGPU::calcEFlags() const {
case ELFABIVERSION_AMDGPU_HSA_V6:
return calcEFlagsV6();
default:
- error("unknown abi version: " + Twine(abiVersion));
+ ErrAlways(ctx) << "unknown abi version: " << Twine(abiVersion);
return 0;
}
}
@@ -193,8 +193,8 @@ RelExpr AMDGPU::getRelExpr(RelType type, const Symbol &s,
case R_AMDGPU_GOTPCREL32_HI:
return R_GOT_PC;
default:
- error(getErrorLoc(ctx, loc) + "unknown relocation (" + Twine(type) +
- ") against symbol " + toString(s));
+ Err(ctx) << getErrorLoc(ctx, loc) << "unknown relocation (" << Twine(type)
+ << ") against symbol " << &s;
return R_NONE;
}
}
diff --git a/lld/ELF/Arch/ARM.cpp b/lld/ELF/Arch/ARM.cpp
index 0df644c61babdd..4c50f7397ad920 100644
--- a/lld/ELF/Arch/ARM.cpp
+++ b/lld/ELF/Arch/ARM.cpp
@@ -195,8 +195,8 @@ RelExpr ARM::getRelExpr(RelType type, const Symbol &s,
// not ARMv4 output, we can just ignore it.
return R_NONE;
default:
- error(getErrorLoc(ctx, loc) + "unknown relocation (" + Twine(type) +
- ") against symbol " + toString(s));
+ Err(ctx) << getErrorLoc(ctx, loc) << "unknown relocation (" << Twine(type)
+ << ") against symbol " << &s;
return R_NONE;
}
}
@@ -556,8 +556,8 @@ void ARM::encodeAluGroup(uint8_t *loc, const Relocation &rel, uint64_t val,
rot = (lz + 8) << 7;
}
if (check && imm > 0xff)
- error(getErrorLoc(ctx, loc) + "unencodeable immediate " + Twine(val).str() +
- " for relocation " + toString(rel.type));
+ Err(ctx) << getErrorLoc(ctx, loc) << "unencodeable immediate "
+ << Twine(val).str() << " for relocation " << rel.type;
write32(ctx, loc,
(read32(ctx, loc) & 0xff3ff000) | opcode | rot | (imm & 0xff));
}
@@ -1216,20 +1216,22 @@ template <class ELFT> void ObjFile<ELFT>::importCmseSymbols() {
sym->stOther = eSym.st_other;
if (eSym.st_shndx != SHN_ABS) {
- error("CMSE symbol '" + sym->getName() + "' in import library '" +
- toString(this) + "' is not absolute");
+ ErrAlways(ctx) << "CMSE symbol '" << sym->getName()
+ << "' in import library '" << this << "' is not absolute";
continue;
}
if (!(eSym.st_value & 1) || (eSym.getType() != STT_FUNC)) {
- error("CMSE symbol '" + sym->getName() + "' in import library '" +
- toString(this) + "' is not a Thumb function definition");
+ ErrAlways(ctx) << "CMSE symbol '" << sym->getName()
+ << "' in import library '" << this
+ << "' is not a Thumb function definition";
continue;
}
if (ctx.symtab->cmseImportLib.count(sym->getName())) {
- error("CMSE symbol '" + sym->getName() +
- "' is multiply defined in import library '" + toString(this) + "'");
+ ErrAlways(ctx) << "CMSE symbol '" << sym->getName()
+ << "' is multiply defined in import library '" << this
+ << "'";
continue;
}
@@ -1283,7 +1285,8 @@ void elf::processArmCmseSymbols(Ctx &ctx) {
// If input object build attributes do not support CMSE, error and disable
// further scanning for <sym>, __acle_se_<sym> pairs.
if (!ctx.arg.armCMSESupport) {
- error("CMSE is only supported by ARMv8-M architecture or later");
+ ErrAlways(ctx)
+ << "CMSE is only supported by ARMv8-M architecture or later";
ctx.arg.cmseImplib = false;
break;
}
@@ -1293,16 +1296,17 @@ void elf::processArmCmseSymbols(Ctx &ctx) {
StringRef name = acleSeSym->getName().substr(std::strlen(ACLESESYM_PREFIX));
Symbol *sym = ctx.symtab->find(name);
if (!sym) {
- error(toString(acleSeSym->file) + ": cmse special symbol '" +
- acleSeSym->getName() +
- "' detected, but no associated entry function definition '" + name +
- "' with external linkage found");
+ ErrAlways(ctx)
+ << acleSeSym->file << ": cmse special symbol '"
+ << acleSeSym->getName()
+ << "' detected, but no associated entry function definition '" << name
+ << "' with external linkage found";
continue;
}
std::string errMsg = checkCmseSymAttributes(acleSeSym, sym);
if (!errMsg.empty()) {
- error(errMsg);
+ ErrAlways(ctx) << errMsg;
continue;
}
@@ -1432,7 +1436,8 @@ void ArmCmseSGSection::finalizeContents() {
// Check if the start address of '.gnu.sgstubs' correspond to the
// linker-synthesized veneer with the lowest address.
if ((getVA() & ~1) != (addr & ~1)) {
- error("start address of '.gnu.sgstubs' is
diff erent from previous link");
+ ErrAlways(ctx)
+ << "start address of '.gnu.sgstubs' is
diff erent from previous link";
return;
}
@@ -1500,8 +1505,8 @@ template <typename ELFT> void elf::writeARMCmseImportLib(Ctx &ctx) {
Expected<std::unique_ptr<FileOutputBuffer>> bufferOrErr =
FileOutputBuffer::create(ctx.arg.cmseOutputLib, fileSize, flags);
if (!bufferOrErr) {
- error("failed to open " + ctx.arg.cmseOutputLib + ": " +
- llvm::toString(bufferOrErr.takeError()));
+ ErrAlways(ctx) << "failed to open " << ctx.arg.cmseOutputLib << ": "
+ << llvm::toString(bufferOrErr.takeError());
return;
}
diff --git a/lld/ELF/Arch/AVR.cpp b/lld/ELF/Arch/AVR.cpp
index 64790f1ce83ab3..5538acd90de428 100644
--- a/lld/ELF/Arch/AVR.cpp
+++ b/lld/ELF/Arch/AVR.cpp
@@ -93,8 +93,8 @@ RelExpr AVR::getRelExpr(RelType type, const Symbol &s,
case R_AVR_13_PCREL:
return R_PC;
default:
- error(getErrorLoc(ctx, loc) + "unknown relocation (" + Twine(type) +
- ") against symbol " + toString(s));
+ Err(ctx) << getErrorLoc(ctx, loc) << "unknown relocation (" << Twine(type)
+ << ") against symbol " << &s;
return R_NONE;
}
}
@@ -282,8 +282,8 @@ uint32_t AVR::calcEFlags() const {
for (InputFile *f : ArrayRef(ctx.objectFiles).slice(1)) {
uint32_t objFlags = getEFlags(f);
if ((objFlags & EF_AVR_ARCH_MASK) != (flags & EF_AVR_ARCH_MASK))
- error(toString(f) +
- ": cannot link object files with incompatible target ISA");
+ ErrAlways(ctx)
+ << f << ": cannot link object files with incompatible target ISA";
if (!(objFlags & EF_AVR_LINKRELAX_PREPARED))
hasLinkRelaxFlag = false;
}
diff --git a/lld/ELF/Arch/Hexagon.cpp b/lld/ELF/Arch/Hexagon.cpp
index 80fcb3b747d1ea..b648b3bdc1da69 100644
--- a/lld/ELF/Arch/Hexagon.cpp
+++ b/lld/ELF/Arch/Hexagon.cpp
@@ -153,8 +153,8 @@ RelExpr Hexagon::getRelExpr(RelType type, const Symbol &s,
case R_HEX_TPREL_LO16:
return R_TPREL;
default:
- error(getErrorLoc(ctx, loc) + "unknown relocation (" + Twine(type) +
- ") against symbol " + toString(s));
+ Err(ctx) << getErrorLoc(ctx, loc) << "unknown relocation (" << Twine(type)
+ << ") against symbol " << &s;
return R_NONE;
}
}
@@ -198,8 +198,8 @@ static uint32_t findMaskR6(uint32_t insn) {
if ((0xff000000 & insn) == i.cmpMask)
return i.relocMask;
- error("unrecognized instruction for 6_X relocation: 0x" +
- utohexstr(insn));
+ ErrAlways(ctx) << "unrecognized instruction for 6_X relocation: 0x"
+ << utohexstr(insn);
return 0;
}
@@ -246,8 +246,8 @@ static uint32_t findMaskR16(uint32_t insn) {
if ((0xff000000 & insn) == i.cmpMask)
return i.relocMask;
- error("unrecognized instruction for 16_X type: 0x" +
- utohexstr(insn));
+ ErrAlways(ctx) << "unrecognized instruction for 16_X type: 0x"
+ << utohexstr(insn);
return 0;
}
diff --git a/lld/ELF/Arch/LoongArch.cpp b/lld/ELF/Arch/LoongArch.cpp
index 79ad0d60051592..b357b22f1b25f3 100644
--- a/lld/ELF/Arch/LoongArch.cpp
+++ b/lld/ELF/Arch/LoongArch.cpp
@@ -250,9 +250,9 @@ uint32_t LoongArch::calcEFlags() const {
if ((flags & EF_LOONGARCH_ABI_MODIFIER_MASK) !=
(target & EF_LOONGARCH_ABI_MODIFIER_MASK))
- error(toString(f) +
- ": cannot link object files with
diff erent ABI from " +
- toString(targetFile));
+ ErrAlways(ctx) << f
+ << ": cannot link object files with
diff erent ABI from "
+ << targetFile;
// We cannot process psABI v1.x / object ABI v0 files (containing stack
// relocations), unlike ld.bfd.
@@ -270,7 +270,7 @@ uint32_t LoongArch::calcEFlags() const {
// and the few impacted users are advised to simply rebuild world or
// reinstall a recent system.
if ((flags & EF_LOONGARCH_OBJABI_MASK) != EF_LOONGARCH_OBJABI_V1)
- error(toString(f) + ": unsupported object file ABI version");
+ ErrAlways(ctx) << f << ": unsupported object file ABI version";
}
return target;
@@ -528,8 +528,8 @@ RelExpr LoongArch::getRelExpr(const RelType type, const Symbol &s,
//
// [1]: https://web.archive.org/web/20230709064026/https://github.com/loongson/LoongArch-Documentation/issues/51
default:
- error(getErrorLoc(ctx, loc) + "unknown relocation (" + Twine(type) +
- ") against symbol " + toString(s));
+ Err(ctx) << getErrorLoc(ctx, loc) << "unknown relocation (" << Twine(type)
+ << ") against symbol " << &s;
return R_NONE;
}
}
diff --git a/lld/ELF/Arch/MSP430.cpp b/lld/ELF/Arch/MSP430.cpp
index 5d48518c53d8df..fc94424e6c7a17 100644
--- a/lld/ELF/Arch/MSP430.cpp
+++ b/lld/ELF/Arch/MSP430.cpp
@@ -83,8 +83,7 @@ void MSP430::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const {
break;
}
default:
- error(getErrorLoc(ctx, loc) + "unrecognized relocation " +
- toString(rel.type));
+ Err(ctx) << getErrorLoc(ctx, loc) << "unrecognized relocation " << rel.type;
}
}
diff --git a/lld/ELF/Arch/Mips.cpp b/lld/ELF/Arch/Mips.cpp
index d84e85239d2ec2..7f6bebb145a090 100644
--- a/lld/ELF/Arch/Mips.cpp
+++ b/lld/ELF/Arch/Mips.cpp
@@ -191,8 +191,8 @@ RelExpr MIPS<ELFT>::getRelExpr(RelType type, const Symbol &s,
case R_MIPS_NONE:
return R_NONE;
default:
- error(getErrorLoc(ctx, loc) + "unknown relocation (" + Twine(type) +
- ") against symbol " + toString(s));
+ Err(ctx) << getErrorLoc(ctx, loc) << "unknown relocation (" << Twine(type)
+ << ") against symbol " << &s;
return R_NONE;
}
}
@@ -503,8 +503,8 @@ calculateMipsRelChain(Ctx &ctx, uint8_t *loc, RelType type, uint64_t val) {
return std::make_pair(type2, val);
if (type2 == R_MIPS_SUB && (type3 == R_MIPS_HI16 || type3 == R_MIPS_LO16))
return std::make_pair(type3, -val);
- error(getErrorLoc(ctx, loc) + "unsupported relocations combination " +
- Twine(type));
+ Err(ctx) << getErrorLoc(ctx, loc) << "unsupported relocations combination "
+ << Twine(type);
return std::make_pair(type & 0xff, val);
}
@@ -562,9 +562,10 @@ static uint64_t fixupCrossModeJump(Ctx &ctx, uint8_t *loc, RelType type,
llvm_unreachable("unexpected jump/branch relocation");
}
- error(getErrorLoc(ctx, loc) +
- "unsupported jump/branch instruction between ISA modes referenced by " +
- toString(type) + " relocation");
+ ErrAlways(ctx)
+ << getErrorLoc(ctx, loc)
+ << "unsupported jump/branch instruction between ISA modes referenced by "
+ << type << " relocation";
return val;
}
diff --git a/lld/ELF/Arch/MipsArchTree.cpp b/lld/ELF/Arch/MipsArchTree.cpp
index 72892c1f8427ae..80af3a3edbd409 100644
--- a/lld/ELF/Arch/MipsArchTree.cpp
+++ b/lld/ELF/Arch/MipsArchTree.cpp
@@ -72,22 +72,24 @@ static void checkFlags(Ctx &ctx, ArrayRef<FileFlags> files) {
for (const FileFlags &f : files) {
if (ctx.arg.is64 && f.flags & EF_MIPS_MICROMIPS)
- error(toString(f.file) + ": microMIPS 64-bit is not supported");
+ ErrAlways(ctx) << f.file << ": microMIPS 64-bit is not supported";
uint32_t abi2 = f.flags & (EF_MIPS_ABI | EF_MIPS_ABI2);
if (abi != abi2)
- error(toString(f.file) + ": ABI '" + getAbiName(abi2) +
- "' is incompatible with target ABI '" + getAbiName(abi) + "'");
+ ErrAlways(ctx) << f.file << ": ABI '" << getAbiName(abi2)
+ << "' is incompatible with target ABI '" << getAbiName(abi)
+ << "'";
bool nan2 = f.flags & EF_MIPS_NAN2008;
if (nan != nan2)
- error(toString(f.file) + ": -mnan=" + getNanName(nan2) +
- " is incompatible with target -mnan=" + getNanName(nan));
+ ErrAlways(ctx) << f.file << ": -mnan=" << getNanName(nan2)
+ << " is incompatible with target -mnan="
+ << getNanName(nan);
bool fp2 = f.flags & EF_MIPS_FP64;
if (fp != fp2)
- error(toString(f.file) + ": -mfp" + getFpName(fp2) +
- " is incompatible with target -mfp" + getFpName(fp));
+ ErrAlways(ctx) << f.file << ": -mfp" << getFpName(fp2)
+ << " is incompatible with target -mfp" << getFpName(fp);
}
}
@@ -284,9 +286,9 @@ static uint32_t getArchFlags(ArrayRef<FileFlags> files) {
if (isArchMatched(newFlags, ret))
continue;
if (!isArchMatched(ret, newFlags)) {
- error("incompatible target ISA:\n>>> " + toString(files[0].file) + ": " +
- getFullArchName(ret) + "\n>>> " + toString(f.file) + ": " +
- getFullArchName(newFlags));
+ ErrAlways(ctx) << "incompatible target ISA:\n>>> " << files[0].file
+ << ": " << getFullArchName(ret) << "\n>>> " << f.file
+ << ": " << getFullArchName(newFlags);
return 0;
}
ret = newFlags;
@@ -355,9 +357,10 @@ uint8_t elf::getMipsFpAbiFlag(uint8_t oldFlag, uint8_t newFlag,
if (compareMipsFpAbi(newFlag, oldFlag) >= 0)
return newFlag;
if (compareMipsFpAbi(oldFlag, newFlag) < 0)
- error(fileName + ": floating point ABI '" + getMipsFpAbiName(newFlag) +
- "' is incompatible with target floating point ABI '" +
- getMipsFpAbiName(oldFlag) + "'");
+ ErrAlways(ctx) << fileName << ": floating point ABI '"
+ << getMipsFpAbiName(newFlag)
+ << "' is incompatible with target floating point ABI '"
+ << getMipsFpAbiName(oldFlag) << "'";
return oldFlag;
}
diff --git a/lld/ELF/Arch/PPC.cpp b/lld/ELF/Arch/PPC.cpp
index 2cd526020f7d35..8b0af6c4a49d70 100644
--- a/lld/ELF/Arch/PPC.cpp
+++ b/lld/ELF/Arch/PPC.cpp
@@ -269,8 +269,8 @@ RelExpr PPC::getRelExpr(RelType type, const Symbol &s,
case R_PPC_TPREL16_HI:
return R_TPREL;
default:
- error(getErrorLoc(ctx, loc) + "unknown relocation (" + Twine(type) +
- ") against symbol " + toString(s));
+ Err(ctx) << getErrorLoc(ctx, loc) << "unknown relocation (" << Twine(type)
+ << ") against symbol " << &s;
return R_NONE;
}
}
@@ -482,14 +482,14 @@ void PPC::relaxTlsIeToLe(uint8_t *loc, const Relocation &rel,
case R_PPC_TLS: {
uint32_t insn = read32(ctx, loc);
if (insn >> 26 != 31)
- error("unrecognized instruction for IE to LE R_PPC_TLS");
+ ErrAlways(ctx) << "unrecognized instruction for IE to LE R_PPC_TLS";
// addi rT, rT, x at tls --> addi rT, rT, x at tprel@l
unsigned secondaryOp = (read32(ctx, loc) & 0x000007fe) >> 1;
uint32_t dFormOp = getPPCDFormOp(secondaryOp);
if (dFormOp == 0) { // Expecting a DS-Form instruction.
dFormOp = getPPCDSFormOp(secondaryOp);
if (dFormOp == 0)
- error("unrecognized instruction for IE to LE R_PPC_TLS");
+ ErrAlways(ctx) << "unrecognized instruction for IE to LE R_PPC_TLS";
}
write32(ctx, loc, (dFormOp | (insn & 0x03ff0000) | lo(val)));
break;
diff --git a/lld/ELF/Arch/PPC64.cpp b/lld/ELF/Arch/PPC64.cpp
index d0f59681ccbd3c..624b5f5e19f789 100644
--- a/lld/ELF/Arch/PPC64.cpp
+++ b/lld/ELF/Arch/PPC64.cpp
@@ -240,7 +240,8 @@ unsigned elf::getPPC64GlobalEntryToLocalEntryOffset(uint8_t stOther) {
if (gepToLep < 7)
return 1 << gepToLep;
- error("reserved value of 7 in the 3 most-significant-bits of st_other");
+ ErrAlways(ctx)
+ << "reserved value of 7 in the 3 most-significant-bits of st_other";
return 0;
}
@@ -642,9 +643,9 @@ uint32_t PPC64::calcEFlags() const {
for (InputFile *f : ctx.objectFiles) {
uint32_t flag = getEFlags(f);
if (flag == 1)
- error(toString(f) + ": ABI version 1 is not supported");
+ ErrAlways(ctx) << f << ": ABI version 1 is not supported";
else if (flag > 2)
- error(toString(f) + ": unrecognized e_flags: " + Twine(flag));
+ ErrAlways(ctx) << f << ": unrecognized e_flags: " << Twine(flag);
}
return 2;
}
@@ -660,7 +661,8 @@ void PPC64::relaxGot(uint8_t *loc, const Relocation &rel, uint64_t val) const {
// "addi reg, 2, var at toc".
uint32_t insn = readFromHalf16(ctx, loc);
if (getPrimaryOpCode(insn) != LD)
- error("expected a 'ld' for got-indirect to toc-relative relaxing");
+ ErrAlways(ctx)
+ << "expected a 'ld' for got-indirect to toc-relative relaxing";
writeFromHalf16(ctx, loc, (insn & 0x03ffffff) | 0x38000000);
relocateNoSym(loc, R_PPC64_TOC16_LO, val);
break;
@@ -670,7 +672,8 @@ void PPC64::relaxGot(uint8_t *loc, const Relocation &rel, uint64_t val) const {
// instruction (the primary opcode).
uint64_t insn = readPrefixedInst(ctx, loc);
if ((insn & 0xfc000000) != 0xe4000000)
- error("expected a 'pld' for got-indirect to pc-relative relaxing");
+ ErrAlways(ctx)
+ << "expected a 'pld' for got-indirect to pc-relative relaxing";
insn &= ~0xff000000fc000000;
// Replace the cleared bits with the values for PADDI (0x600000038000000);
@@ -933,14 +936,14 @@ void PPC64::relaxTlsIeToLe(uint8_t *loc, const Relocation &rel,
if (locAsInt % 4 == 0) {
uint32_t primaryOp = getPrimaryOpCode(read32(ctx, loc));
if (primaryOp != 31)
- error("unrecognized instruction for IE to LE R_PPC64_TLS");
+ ErrAlways(ctx) << "unrecognized instruction for IE to LE R_PPC64_TLS";
uint32_t secondaryOp = (read32(ctx, loc) & 0x000007fe) >> 1; // bits 21-30
uint32_t dFormOp = getPPCDFormOp(secondaryOp);
uint32_t finalReloc;
if (dFormOp == 0) { // Expecting a DS-Form instruction.
dFormOp = getPPCDSFormOp(secondaryOp);
if (dFormOp == 0)
- error("unrecognized instruction for IE to LE R_PPC64_TLS");
+ ErrAlways(ctx) << "unrecognized instruction for IE to LE R_PPC64_TLS";
finalReloc = R_PPC64_TPREL16_LO_DS;
} else
finalReloc = R_PPC64_TPREL16_LO;
@@ -1098,8 +1101,8 @@ RelExpr PPC64::getRelExpr(RelType type, const Symbol &s,
case R_PPC64_TLS:
return R_TLSIE_HINT;
default:
- error(getErrorLoc(ctx, loc) + "unknown relocation (" + Twine(type) +
- ") against symbol " + toString(s));
+ Err(ctx) << getErrorLoc(ctx, loc) << "unknown relocation (" << Twine(type)
+ << ") against symbol " << &s;
return R_NONE;
}
}
@@ -1334,8 +1337,9 @@ void PPC64::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const {
if (ctx.arg.tocOptimize && shouldTocOptimize && ha(val) == 0) {
uint32_t insn = readFromHalf16(ctx, loc);
if (isInstructionUpdateForm(insn))
- error(getErrorLoc(ctx, loc) +
- "can't toc-optimize an update instruction: 0x" + utohexstr(insn));
+ Err(ctx) << getErrorLoc(ctx, loc)
+ << "can't toc-optimize an update instruction: 0x"
+ << utohexstr(insn);
writeFromHalf16(ctx, loc, (insn & 0xffe00000) | 0x00020000 | lo(val));
} else {
write16(ctx, loc, lo(val));
@@ -1353,9 +1357,9 @@ void PPC64::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const {
// changed into a nop. The lo part then needs to be updated to use the toc
// pointer register r2, as the base register.
if (isInstructionUpdateForm(insn))
- error(getErrorLoc(ctx, loc) +
- "Can't toc-optimize an update instruction: 0x" +
- Twine::utohexstr(insn));
+ Err(ctx) << getErrorLoc(ctx, loc)
+ << "Can't toc-optimize an update instruction: 0x"
+ << Twine::utohexstr(insn);
insn &= 0xffe00000 | mask;
writeFromHalf16(ctx, loc, insn | 0x00020000 | lo(val));
} else {
@@ -1726,7 +1730,8 @@ bool PPC64::adjustPrologueForCrossSplitStack(uint8_t *loc, uint8_t *end,
// Check that the adjusted size doesn't overflow what we can represent with 2
// instructions.
if (stackFrameSize < ctx.arg.splitStackAdjustSize + INT32_MIN) {
- error(getErrorLoc(ctx, loc) + "split-stack prologue adjustment overflows");
+ Err(ctx) << getErrorLoc(ctx, loc)
+ << "split-stack prologue adjustment overflows";
return false;
}
diff --git a/lld/ELF/Arch/RISCV.cpp b/lld/ELF/Arch/RISCV.cpp
index 888495962d9762..4a8e8fcefe41ea 100644
--- a/lld/ELF/Arch/RISCV.cpp
+++ b/lld/ELF/Arch/RISCV.cpp
@@ -156,14 +156,14 @@ uint32_t RISCV::calcEFlags() const {
target |= EF_RISCV_RVC;
if ((eflags & EF_RISCV_FLOAT_ABI) != (target & EF_RISCV_FLOAT_ABI))
- error(
- toString(f) +
- ": cannot link object files with
diff erent floating-point ABI from " +
- toString(ctx.objectFiles[0]));
+ ErrAlways(ctx) << f
+ << ": cannot link object files with
diff erent "
+ "floating-point ABI from "
+ << ctx.objectFiles[0];
if ((eflags & EF_RISCV_RVE) != (target & EF_RISCV_RVE))
- error(toString(f) +
- ": cannot link object files with
diff erent EF_RISCV_RVE");
+ ErrAlways(ctx)
+ << f << ": cannot link object files with
diff erent EF_RISCV_RVE";
}
return target;
@@ -325,8 +325,8 @@ RelExpr RISCV::getRelExpr(const RelType type, const Symbol &s,
case R_RISCV_SUB_ULEB128:
return R_RISCV_LEB128;
default:
- error(getErrorLoc(ctx, loc) + "unknown relocation (" + Twine(type) +
- ") against symbol " + toString(s));
+ Err(ctx) << getErrorLoc(ctx, loc) << "unknown relocation (" << Twine(type)
+ << ") against symbol " << &s;
return R_NONE;
}
}
diff --git a/lld/ELF/Arch/SPARCV9.cpp b/lld/ELF/Arch/SPARCV9.cpp
index ef71014e12fa97..d733f2e0a43909 100644
--- a/lld/ELF/Arch/SPARCV9.cpp
+++ b/lld/ELF/Arch/SPARCV9.cpp
@@ -78,8 +78,8 @@ RelExpr SPARCV9::getRelExpr(RelType type, const Symbol &s,
case R_SPARC_TLS_LE_LOX10:
return R_TPREL;
default:
- error(getErrorLoc(ctx, loc) + "unknown relocation (" + Twine(type) +
- ") against symbol " + toString(s));
+ Err(ctx) << getErrorLoc(ctx, loc) << "unknown relocation (" << Twine(type)
+ << ") against symbol " << &s;
return R_NONE;
}
}
diff --git a/lld/ELF/Arch/SystemZ.cpp b/lld/ELF/Arch/SystemZ.cpp
index 106b530c31b28b..3b78ce14aa1224 100644
--- a/lld/ELF/Arch/SystemZ.cpp
+++ b/lld/ELF/Arch/SystemZ.cpp
@@ -170,8 +170,8 @@ RelExpr SystemZ::getRelExpr(RelType type, const Symbol &s,
return R_GOT_PC;
default:
- error(getErrorLoc(ctx, loc) + "unknown relocation (" + Twine(type) +
- ") against symbol " + toString(s));
+ Err(ctx) << getErrorLoc(ctx, loc) << "unknown relocation (" << Twine(type)
+ << ") against symbol " << &s;
return R_NONE;
}
}
diff --git a/lld/ELF/Arch/X86.cpp b/lld/ELF/Arch/X86.cpp
index a36212a5b1690a..ac69d032e2fbff 100644
--- a/lld/ELF/Arch/X86.cpp
+++ b/lld/ELF/Arch/X86.cpp
@@ -151,8 +151,8 @@ RelExpr X86::getRelExpr(RelType type, const Symbol &s,
case R_386_NONE:
return R_NONE;
default:
- error(getErrorLoc(ctx, loc) + "unknown relocation (" + Twine(type) +
- ") against symbol " + toString(s));
+ Err(ctx) << getErrorLoc(ctx, loc) << "unknown relocation (" << Twine(type)
+ << ") against symbol " << &s;
return R_NONE;
}
}
@@ -372,8 +372,9 @@ void X86::relaxTlsGdToLe(uint8_t *loc, const Relocation &rel,
//
// Note: call *x at tlsdesc(%eax) may not immediately follow this instruction.
if (memcmp(loc - 2, "\x8d\x83", 2)) {
- error(getErrorLoc(ctx, loc - 2) +
- "R_386_TLS_GOTDESC must be used in leal x at tlsdesc(%ebx), %eax");
+ ErrAlways(ctx)
+ << getErrorLoc(ctx, loc - 2)
+ << "R_386_TLS_GOTDESC must be used in leal x at tlsdesc(%ebx), %eax";
return;
}
loc[-1] = 0x05;
@@ -405,8 +406,9 @@ void X86::relaxTlsGdToIe(uint8_t *loc, const Relocation &rel,
} else if (rel.type == R_386_TLS_GOTDESC) {
// Convert leal x at tlsdesc(%ebx), %eax to movl x at gotntpoff(%ebx), %eax.
if (memcmp(loc - 2, "\x8d\x83", 2)) {
- error(getErrorLoc(ctx, loc - 2) +
- "R_386_TLS_GOTDESC must be used in leal x at tlsdesc(%ebx), %eax");
+ ErrAlways(ctx)
+ << getErrorLoc(ctx, loc - 2)
+ << "R_386_TLS_GOTDESC must be used in leal x at tlsdesc(%ebx), %eax";
return;
}
loc[-2] = 0x8b;
diff --git a/lld/ELF/Arch/X86_64.cpp b/lld/ELF/Arch/X86_64.cpp
index d32ba638b740c5..c3031b1f9a68a8 100644
--- a/lld/ELF/Arch/X86_64.cpp
+++ b/lld/ELF/Arch/X86_64.cpp
@@ -407,8 +407,8 @@ RelExpr X86_64::getRelExpr(RelType type, const Symbol &s,
case R_X86_64_NONE:
return R_NONE;
default:
- error(getErrorLoc(ctx, loc) + "unknown relocation (" + Twine(type) +
- ") against symbol " + toString(s));
+ Err(ctx) << getErrorLoc(ctx, loc) << "unknown relocation (" << Twine(type)
+ << ") against symbol " << &s;
return R_NONE;
}
}
@@ -582,8 +582,9 @@ void X86_64::relaxTlsIeToLe(uint8_t *loc, const Relocation &rel,
memcpy(inst, "\x48\xc7", 2);
*regSlot = 0xc0 | reg;
} else {
- error(getErrorLoc(ctx, loc - 3) +
- "R_X86_64_GOTTPOFF must be used in MOVQ or ADDQ instructions only");
+ ErrAlways(ctx)
+ << getErrorLoc(ctx, loc - 3)
+ << "R_X86_64_GOTTPOFF must be used in MOVQ or ADDQ instructions only";
}
// The original code used a PC relative relocation.
@@ -627,8 +628,9 @@ void X86_64::relaxTlsLdToLe(uint8_t *loc, const Relocation &rel,
return;
}
- error(getErrorLoc(ctx, loc - 3) +
- "expected R_X86_64_PLT32 or R_X86_64_GOTPCRELX after R_X86_64_TLSLD");
+ ErrAlways(ctx)
+ << getErrorLoc(ctx, loc - 3)
+ << "expected R_X86_64_PLT32 or R_X86_64_GOTPCRELX after R_X86_64_TLSLD";
}
// A JumpInstrMod at a specific offset indicates that the jump instruction
@@ -1031,7 +1033,7 @@ static void relaxGot(uint8_t *loc, const Relocation &rel, uint64_t val) {
bool X86_64::adjustPrologueForCrossSplitStack(uint8_t *loc, uint8_t *end,
uint8_t stOther) const {
if (!ctx.arg.is64) {
- error("target doesn't support split stacks");
+ ErrAlways(ctx) << "target doesn't support split stacks";
return false;
}
diff --git a/lld/ELF/CallGraphSort.cpp b/lld/ELF/CallGraphSort.cpp
index 537e065081f3fc..35c59d6edb2ad1 100644
--- a/lld/ELF/CallGraphSort.cpp
+++ b/lld/ELF/CallGraphSort.cpp
@@ -248,7 +248,8 @@ DenseMap<const InputSectionBase *, int> CallGraphSort::run() {
std::error_code ec;
raw_fd_ostream os(ctx.arg.printSymbolOrder, ec, sys::fs::OF_None);
if (ec) {
- error("cannot open " + ctx.arg.printSymbolOrder + ": " + ec.message());
+ ErrAlways(ctx) << "cannot open " << ctx.arg.printSymbolOrder << ": "
+ << ec.message();
return orderMap;
}
diff --git a/lld/ELF/Config.h b/lld/ELF/Config.h
index 91555573307b74..56db089ec876b4 100644
--- a/lld/ELF/Config.h
+++ b/lld/ELF/Config.h
@@ -700,6 +700,11 @@ inline const ELFSyncStream &operator<<(const ELFSyncStream &s, const char *v) {
return s;
}
+inline const ELFSyncStream &operator<<(const ELFSyncStream &s, Error v) {
+ s.os << llvm::toString(std::move(v));
+ return s;
+}
+
// Report a log if --verbose is specified.
ELFSyncStream Log(Ctx &ctx);
diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp
index 75d7f934a990d6..c1832325b22b25 100644
--- a/lld/ELF/Driver.cpp
+++ b/lld/ELF/Driver.cpp
@@ -88,7 +88,7 @@ void elf::errorOrWarn(const Twine &msg) {
if (ctx.arg.noinhibitExec)
warn(msg);
else
- error(msg);
+ ErrAlways(ctx) << msg;
}
ELFSyncStream elf::Log(Ctx &ctx) { return {ctx, DiagLevel::Log}; }
@@ -235,7 +235,7 @@ static std::tuple<ELFKind, uint16_t, uint8_t> parseEmulation(StringRef emul) {
.Default({ELFNoneKind, EM_NONE});
if (ret.first == ELFNoneKind)
- error("unknown emulation: " + emul);
+ ErrAlways(ctx) << "unknown emulation: " << emul;
if (ret.second == EM_MSP430)
osabi = ELFOSABI_STANDALONE;
else if (ret.second == EM_AMDGPU)
@@ -355,7 +355,7 @@ void LinkerDriver::addFile(StringRef path, bool withLOption) {
}
case file_magic::elf_shared_object: {
if (ctx.arg.isStatic) {
- error("attempted static link of dynamic object " + path);
+ ErrAlways(ctx) << "attempted static link of dynamic object " << path;
return;
}
@@ -407,106 +407,109 @@ static void checkOptions(Ctx &ctx) {
// The MIPS ABI as of 2016 does not support the GNU-style symbol lookup
// table which is a relatively new feature.
if (ctx.arg.emachine == EM_MIPS && ctx.arg.gnuHash)
- error("the .gnu.hash section is not compatible with the MIPS target");
+ ErrAlways(ctx)
+ << "the .gnu.hash section is not compatible with the MIPS target";
if (ctx.arg.emachine == EM_ARM) {
if (!ctx.arg.cmseImplib) {
if (!ctx.arg.cmseInputLib.empty())
- error("--in-implib may not be used without --cmse-implib");
+ ErrAlways(ctx) << "--in-implib may not be used without --cmse-implib";
if (!ctx.arg.cmseOutputLib.empty())
- error("--out-implib may not be used without --cmse-implib");
+ ErrAlways(ctx) << "--out-implib may not be used without --cmse-implib";
}
} else {
if (ctx.arg.cmseImplib)
- error("--cmse-implib is only supported on ARM targets");
+ ErrAlways(ctx) << "--cmse-implib is only supported on ARM targets";
if (!ctx.arg.cmseInputLib.empty())
- error("--in-implib is only supported on ARM targets");
+ ErrAlways(ctx) << "--in-implib is only supported on ARM targets";
if (!ctx.arg.cmseOutputLib.empty())
- error("--out-implib is only supported on ARM targets");
+ ErrAlways(ctx) << "--out-implib is only supported on ARM targets";
}
if (ctx.arg.fixCortexA53Errata843419 && ctx.arg.emachine != EM_AARCH64)
- error("--fix-cortex-a53-843419 is only supported on AArch64 targets");
+ ErrAlways(ctx)
+ << "--fix-cortex-a53-843419 is only supported on AArch64 targets";
if (ctx.arg.fixCortexA8 && ctx.arg.emachine != EM_ARM)
- error("--fix-cortex-a8 is only supported on ARM targets");
+ ErrAlways(ctx) << "--fix-cortex-a8 is only supported on ARM targets";
if (ctx.arg.armBe8 && ctx.arg.emachine != EM_ARM)
- error("--be8 is only supported on ARM targets");
+ ErrAlways(ctx) << "--be8 is only supported on ARM targets";
if (ctx.arg.fixCortexA8 && !ctx.arg.isLE)
- error("--fix-cortex-a8 is not supported on big endian targets");
+ ErrAlways(ctx) << "--fix-cortex-a8 is not supported on big endian targets";
if (ctx.arg.tocOptimize && ctx.arg.emachine != EM_PPC64)
- error("--toc-optimize is only supported on PowerPC64 targets");
+ ErrAlways(ctx) << "--toc-optimize is only supported on PowerPC64 targets";
if (ctx.arg.pcRelOptimize && ctx.arg.emachine != EM_PPC64)
- error("--pcrel-optimize is only supported on PowerPC64 targets");
+ ErrAlways(ctx) << "--pcrel-optimize is only supported on PowerPC64 targets";
if (ctx.arg.relaxGP && ctx.arg.emachine != EM_RISCV)
- error("--relax-gp is only supported on RISC-V targets");
+ ErrAlways(ctx) << "--relax-gp is only supported on RISC-V targets";
if (ctx.arg.pie && ctx.arg.shared)
- error("-shared and -pie may not be used together");
+ ErrAlways(ctx) << "-shared and -pie may not be used together";
if (!ctx.arg.shared && !ctx.arg.filterList.empty())
- error("-F may not be used without -shared");
+ ErrAlways(ctx) << "-F may not be used without -shared";
if (!ctx.arg.shared && !ctx.arg.auxiliaryList.empty())
- error("-f may not be used without -shared");
+ ErrAlways(ctx) << "-f may not be used without -shared";
if (ctx.arg.strip == StripPolicy::All && ctx.arg.emitRelocs)
- error("--strip-all and --emit-relocs may not be used together");
+ ErrAlways(ctx) << "--strip-all and --emit-relocs may not be used together";
if (ctx.arg.zText && ctx.arg.zIfuncNoplt)
- error("-z text and -z ifunc-noplt may not be used together");
+ ErrAlways(ctx) << "-z text and -z ifunc-noplt may not be used together";
if (ctx.arg.relocatable) {
if (ctx.arg.shared)
- error("-r and -shared may not be used together");
+ ErrAlways(ctx) << "-r and -shared may not be used together";
if (ctx.arg.gdbIndex)
- error("-r and --gdb-index may not be used together");
+ ErrAlways(ctx) << "-r and --gdb-index may not be used together";
if (ctx.arg.icf != ICFLevel::None)
- error("-r and --icf may not be used together");
+ ErrAlways(ctx) << "-r and --icf may not be used together";
if (ctx.arg.pie)
- error("-r and -pie may not be used together");
+ ErrAlways(ctx) << "-r and -pie may not be used together";
if (ctx.arg.exportDynamic)
- error("-r and --export-dynamic may not be used together");
+ ErrAlways(ctx) << "-r and --export-dynamic may not be used together";
if (ctx.arg.debugNames)
- error("-r and --debug-names may not be used together");
+ ErrAlways(ctx) << "-r and --debug-names may not be used together";
if (!ctx.arg.zSectionHeader)
- error("-r and -z nosectionheader may not be used together");
+ ErrAlways(ctx) << "-r and -z nosectionheader may not be used together";
}
if (ctx.arg.executeOnly) {
if (ctx.arg.emachine != EM_AARCH64)
- error("--execute-only is only supported on AArch64 targets");
+ ErrAlways(ctx) << "--execute-only is only supported on AArch64 targets";
if (ctx.arg.singleRoRx && !ctx.script->hasSectionsCommand)
- error("--execute-only and --no-rosegment cannot be used together");
+ ErrAlways(ctx)
+ << "--execute-only and --no-rosegment cannot be used together";
}
if (ctx.arg.zRetpolineplt && ctx.arg.zForceIbt)
- error("-z force-ibt may not be used with -z retpolineplt");
+ ErrAlways(ctx) << "-z force-ibt may not be used with -z retpolineplt";
if (ctx.arg.emachine != EM_AARCH64) {
if (ctx.arg.zPacPlt)
- error("-z pac-plt only supported on AArch64");
+ ErrAlways(ctx) << "-z pac-plt only supported on AArch64";
if (ctx.arg.zForceBti)
- error("-z force-bti only supported on AArch64");
+ ErrAlways(ctx) << "-z force-bti only supported on AArch64";
if (ctx.arg.zBtiReport != "none")
- error("-z bti-report only supported on AArch64");
+ ErrAlways(ctx) << "-z bti-report only supported on AArch64";
if (ctx.arg.zPauthReport != "none")
- error("-z pauth-report only supported on AArch64");
+ ErrAlways(ctx) << "-z pauth-report only supported on AArch64";
if (ctx.arg.zGcsReport != "none")
- error("-z gcs-report only supported on AArch64");
+ ErrAlways(ctx) << "-z gcs-report only supported on AArch64";
if (ctx.arg.zGcs != GcsPolicy::Implicit)
- error("-z gcs only supported on AArch64");
+ ErrAlways(ctx) << "-z gcs only supported on AArch64";
}
if (ctx.arg.emachine != EM_386 && ctx.arg.emachine != EM_X86_64 &&
ctx.arg.zCetReport != "none")
- error("-z cet-report only supported on X86 and X86_64");
+ ErrAlways(ctx) << "-z cet-report only supported on X86 and X86_64";
}
static const char *getReproduceOption(opt::InputArgList &args) {
@@ -589,8 +592,8 @@ static uint8_t getZStartStopVisibility(opt::InputArgList &args) {
else if (kv.second == "protected")
ret = STV_PROTECTED;
else
- error("unknown -z start-stop-visibility= value: " +
- StringRef(kv.second));
+ ErrAlways(ctx) << "unknown -z start-stop-visibility= value: "
+ << StringRef(kv.second);
}
}
return ret;
@@ -609,7 +612,7 @@ static GcsPolicy getZGcs(opt::InputArgList &args) {
else if (kv.second == "always")
ret = GcsPolicy::Always;
else
- error("unknown -z gcs= value: " + kv.second);
+ ErrAlways(ctx) << "unknown -z gcs= value: " << kv.second;
}
}
return ret;
@@ -680,7 +683,7 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
if (!ltoSampleProfile.empty())
readFile(ctx, ltoSampleProfile);
} else {
- error("--reproduce: " + toString(errOrWriter.takeError()));
+ ErrAlways(ctx) << "--reproduce: " << toString(errOrWriter.takeError());
}
}
@@ -755,7 +758,7 @@ static void setUnresolvedSymbolPolicy(Ctx &ctx, opt::InputArgList &args) {
diagRegular = true;
diagShlib = true;
} else {
- error("unknown --unresolved-symbols value: " + s);
+ ErrAlways(ctx) << "unknown --unresolved-symbols value: " << s;
}
break;
}
@@ -794,7 +797,7 @@ static Target2Policy getTarget2(opt::InputArgList &args) {
return Target2Policy::Abs;
if (s == "got-rel")
return Target2Policy::GotRel;
- error("unknown --target2 option: " + s);
+ ErrAlways(ctx) << "unknown --target2 option: " << s;
return Target2Policy::GotRel;
}
@@ -803,7 +806,7 @@ static bool isOutputFormatBinary(opt::InputArgList &args) {
if (s == "binary")
return true;
if (!s.starts_with("elf"))
- error("unknown --oformat value: " + s);
+ ErrAlways(ctx) << "unknown --oformat value: " << s;
return false;
}
@@ -850,8 +853,8 @@ static int getMemtagMode(Ctx &ctx, opt::InputArgList &args) {
if (memtagModeArg == "none")
return ELF::NT_MEMTAG_LEVEL_NONE;
- error("unknown --android-memtag-mode value: \"" + memtagModeArg +
- "\", should be one of {async, sync, none}");
+ ErrAlways(ctx) << "unknown --android-memtag-mode value: \"" << memtagModeArg
+ << "\", should be one of {async, sync, none}";
return ELF::NT_MEMTAG_LEVEL_NONE;
}
@@ -883,7 +886,7 @@ static uint64_t parseSectionAddress(StringRef s, opt::InputArgList &args,
uint64_t va = 0;
s.consume_front("0x");
if (!to_integer(s, va, 16))
- error("invalid argument: " + arg.getAsString(args));
+ ErrAlways(ctx) << "invalid argument: " << arg.getAsString(args);
return va;
}
@@ -912,7 +915,7 @@ static SortSectionPolicy getSortSection(opt::InputArgList &args) {
if (s == "name")
return SortSectionPolicy::Name;
if (!s.empty())
- error("unknown --sort-section rule: " + s);
+ ErrAlways(ctx) << "unknown --sort-section rule: " << s;
return SortSectionPolicy::Default;
}
@@ -923,7 +926,7 @@ static OrphanHandlingPolicy getOrphanHandling(opt::InputArgList &args) {
if (s == "error")
return OrphanHandlingPolicy::Error;
if (s != "place")
- error("unknown --orphan-handling mode: " + s);
+ ErrAlways(ctx) << "unknown --orphan-handling mode: " << s;
return OrphanHandlingPolicy::Place;
}
@@ -949,7 +952,7 @@ getBuildId(opt::InputArgList &args) {
return {BuildIdKind::Hexstring, parseHex(s.substr(2))};
if (s != "none")
- error("unknown --build-id style: " + s);
+ ErrAlways(ctx) << "unknown --build-id style: " << s;
return {BuildIdKind::None, {}};
}
@@ -963,7 +966,7 @@ static std::pair<bool, bool> getPackDynRelocs(opt::InputArgList &args) {
return {true, true};
if (s != "none")
- error("unknown --pack-dyn-relocs format: " + s);
+ ErrAlways(ctx) << "unknown --pack-dyn-relocs format: " << s;
return {false, false};
}
@@ -994,7 +997,7 @@ static void readCallGraph(Ctx &ctx, MemoryBufferRef mb) {
uint64_t count;
if (fields.size() != 3 || !to_integer(fields[2], count)) {
- error(mb.getBufferIdentifier() + ": parse error");
+ ErrAlways(ctx) << mb.getBufferIdentifier() << ": parse error";
return;
}
@@ -1125,12 +1128,14 @@ static void ltoValidateAllVtablesHaveTypeInfos(Ctx &ctx,
for (auto *arg : args.filtered(OPT_lto_known_safe_vtables)) {
StringRef knownSafeName = arg->getValue();
if (!knownSafeName.consume_front("_ZTV"))
- error("--lto-known-safe-vtables=: expected symbol to start with _ZTV, "
- "but got " +
- knownSafeName);
+ ErrAlways(ctx)
+ << "--lto-known-safe-vtables=: expected symbol to start with _ZTV, "
+ "but got "
+ << knownSafeName;
Expected<GlobPattern> pat = GlobPattern::create(knownSafeName);
if (!pat)
- error("--lto-known-safe-vtables=: " + toString(pat.takeError()));
+ ErrAlways(ctx) << "--lto-known-safe-vtables=: "
+ << toString(pat.takeError());
vtableSymbolsWithNoRTTI.remove_if(
[&](StringRef s) { return pat->match(s); });
}
@@ -1152,7 +1157,7 @@ static CGProfileSortKind getCGProfileSortKind(opt::InputArgList &args) {
if (s == "cdsort")
return CGProfileSortKind::Cdsort;
if (s != "none")
- error("unknown --call-graph-profile-sort= value: " + s);
+ ErrAlways(ctx) << "unknown --call-graph-profile-sort= value: " << s;
return CGProfileSortKind::None;
}
@@ -1163,10 +1168,10 @@ static DebugCompressionType getCompressionType(StringRef s, StringRef option) {
.Default(DebugCompressionType::None);
if (type == DebugCompressionType::None) {
if (s != "none")
- error("unknown " + option + " value: " + s);
+ ErrAlways(ctx) << "unknown " << option << " value: " << s;
} else if (const char *reason = compression::getReasonIfUnsupported(
compression::formatFor(type))) {
- error(option + ": " + reason);
+ ErrAlways(ctx) << option << ": " << reason;
}
return type;
}
@@ -1186,7 +1191,8 @@ static std::pair<StringRef, StringRef> getOldNewOptions(opt::InputArgList &args,
StringRef s = arg->getValue();
std::pair<StringRef, StringRef> ret = s.split(';');
if (ret.second.empty())
- error(getAliasSpelling(arg) + " expects 'old;new' format, but got " + s);
+ ErrAlways(ctx) << getAliasSpelling(arg)
+ << " expects 'old;new' format, but got " << s;
return ret;
}
@@ -1235,7 +1241,7 @@ static void parseClangOption(Ctx &ctx, StringRef opt, const Twine &msg) {
const char *argv[] = {ctx.arg.progName.data(), opt.data()};
if (cl::ParseCommandLineOptions(2, argv, "", &os))
return;
- error(msg + ": " + StringRef(err).trim());
+ ErrAlways(ctx) << msg << ": " << StringRef(err).trim();
}
// Checks the parameter of the bti-report and cet-report options.
@@ -1248,7 +1254,7 @@ static bool remapInputs(Ctx &ctx, StringRef line, const Twine &location) {
SmallVector<StringRef, 0> fields;
line.split(fields, '=');
if (fields.size() != 2 || fields[1].empty()) {
- error(location + ": parse error, not 'from-glob=to-file'");
+ ErrAlways(ctx) << location << ": parse error, not 'from-glob=to-file'";
return true;
}
if (!hasWildcard(fields[0]))
@@ -1256,7 +1262,8 @@ static bool remapInputs(Ctx &ctx, StringRef line, const Twine &location) {
else if (Expected<GlobPattern> pat = GlobPattern::create(fields[0]))
ctx.arg.remapInputsWildcards.emplace_back(std::move(*pat), fields[1]);
else {
- error(location + ": " + toString(pat.takeError()) + ": " + fields[0]);
+ ErrAlways(ctx) << location << ": " << toString(pat.takeError()) << ": "
+ << fields[0];
return true;
}
return false;
@@ -1367,13 +1374,15 @@ static void readConfigs(Ctx &ctx, opt::InputArgList &args) {
OPT_no_lto_validate_all_vtables_have_type_infos, false);
ctx.arg.ltoo = args::getInteger(args, OPT_lto_O, 2);
if (ctx.arg.ltoo > 3)
- error("invalid optimization level for LTO: " + Twine(ctx.arg.ltoo));
+ ErrAlways(ctx) << "invalid optimization level for LTO: "
+ << Twine(ctx.arg.ltoo);
unsigned ltoCgo =
args::getInteger(args, OPT_lto_CGO, args::getCGOptLevel(ctx.arg.ltoo));
if (auto level = CodeGenOpt::getLevel(ltoCgo))
ctx.arg.ltoCgo = *level;
else
- error("invalid codegen optimization level for LTO: " + Twine(ltoCgo));
+ ErrAlways(ctx) << "invalid codegen optimization level for LTO: "
+ << Twine(ltoCgo);
ctx.arg.ltoObjPath = args.getLastArgValue(OPT_lto_obj_path_eq);
ctx.arg.ltoPartitions = args::getInteger(args, OPT_lto_partitions, 1);
ctx.arg.ltoSampleProfile = args.getLastArgValue(OPT_lto_sample_profile);
@@ -1403,8 +1412,9 @@ static void readConfigs(Ctx &ctx, opt::InputArgList &args) {
if (auto *arg = args.getLastArg(OPT_opt_remarks_hotness_threshold)) {
auto resultOrErr = remarks::parseHotnessThresholdOption(arg->getValue());
if (!resultOrErr)
- error(arg->getSpelling() + ": invalid argument '" + arg->getValue() +
- "', only integer or 'auto' is supported");
+ ErrAlways(ctx) << arg->getSpelling() << ": invalid argument '"
+ << arg->getValue()
+ << "', only integer or 'auto' is supported";
else
ctx.arg.optRemarksHotnessThreshold = *resultOrErr;
}
@@ -1442,7 +1452,7 @@ static void readConfigs(Ctx &ctx, opt::InputArgList &args) {
if (llvm::is_contained(saveTempsValues, s))
ctx.arg.saveTempsArgs.insert(s);
else
- error("unknown --save-temps value: " + s);
+ ErrAlways(ctx) << "unknown --save-temps value: " << s;
}
}
@@ -1478,16 +1488,17 @@ static void readConfigs(Ctx &ctx, opt::InputArgList &args) {
getOldNewOptionsExtra(args, OPT_thinlto_prefix_replace_eq);
if (ctx.arg.thinLTOEmitIndexFiles && !ctx.arg.thinLTOIndexOnly) {
if (args.hasArg(OPT_thinlto_object_suffix_replace_eq))
- error("--thinlto-object-suffix-replace is not supported with "
- "--thinlto-emit-index-files");
+ ErrAlways(ctx) << "--thinlto-object-suffix-replace is not supported with "
+ "--thinlto-emit-index-files";
else if (args.hasArg(OPT_thinlto_prefix_replace_eq))
- error("--thinlto-prefix-replace is not supported with "
- "--thinlto-emit-index-files");
+ ErrAlways(ctx) << "--thinlto-prefix-replace is not supported with "
+ "--thinlto-emit-index-files";
}
if (!ctx.arg.thinLTOPrefixReplaceNativeObject.empty() &&
ctx.arg.thinLTOIndexOnlyArg.empty()) {
- error("--thinlto-prefix-replace=old_dir;new_dir;obj_dir must be used with "
- "--thinlto-index-only=");
+ ErrAlways(ctx)
+ << "--thinlto-prefix-replace=old_dir;new_dir;obj_dir must be used with "
+ "--thinlto-index-only=";
}
ctx.arg.thinLTOModulesToCompile =
args::getStrings(args, OPT_thinlto_single_module_eq);
@@ -1568,18 +1579,20 @@ static void readConfigs(Ctx &ctx, opt::InputArgList &args) {
constexpr StringRef errPrefix = "--shuffle-sections=: ";
std::pair<StringRef, StringRef> kv = StringRef(arg->getValue()).split('=');
if (kv.first.empty() || kv.second.empty()) {
- error(errPrefix + "expected <section_glob>=<seed>, but got '" +
- arg->getValue() + "'");
+ ErrAlways(ctx) << errPrefix << "expected <section_glob>=<seed>, but got '"
+ << arg->getValue() << "'";
continue;
}
// Signed so that <section_glob>=-1 is allowed.
int64_t v;
if (!to_integer(kv.second, v))
- error(errPrefix + "expected an integer, but got '" + kv.second + "'");
+ ErrAlways(ctx) << errPrefix << "expected an integer, but got '"
+ << kv.second << "'";
else if (Expected<GlobPattern> pat = GlobPattern::create(kv.first))
ctx.arg.shuffleSections.emplace_back(std::move(*pat), uint32_t(v));
else
- error(errPrefix + toString(pat.takeError()) + ": " + kv.first);
+ ErrAlways(ctx) << errPrefix << toString(pat.takeError()) << ": "
+ << kv.first;
}
auto reports = {std::make_pair("bti-report", &ctx.arg.zBtiReport),
@@ -1594,8 +1607,8 @@ static void readConfigs(Ctx &ctx, opt::InputArgList &args) {
continue;
arg->claim();
if (!isValidReportString(option.second)) {
- error(Twine("-z ") + reportArg.first + "= parameter " + option.second +
- " is not recognized");
+ ErrAlways(ctx) << Twine("-z ") << reportArg.first << "= parameter "
+ << option.second << " is not recognized";
continue;
}
*reportArg.second = option.second;
@@ -1606,8 +1619,8 @@ static void readConfigs(Ctx &ctx, opt::InputArgList &args) {
SmallVector<StringRef, 0> fields;
StringRef(arg->getValue()).split(fields, '=');
if (fields.size() != 2 || fields[1].empty()) {
- error(arg->getSpelling() +
- ": parse error, not 'section-glob=[none|zlib|zstd]'");
+ ErrAlways(ctx) << arg->getSpelling()
+ << ": parse error, not 'section-glob=[none|zlib|zstd]'";
continue;
}
auto [typeStr, levelStr] = fields[1].split(':');
@@ -1615,14 +1628,15 @@ static void readConfigs(Ctx &ctx, opt::InputArgList &args) {
unsigned level = 0;
if (fields[1].size() != typeStr.size() &&
!llvm::to_integer(levelStr, level)) {
- error(arg->getSpelling() +
- ": expected a non-negative integer compression level, but got '" +
- levelStr + "'");
+ ErrAlways(ctx)
+ << arg->getSpelling()
+ << ": expected a non-negative integer compression level, but got '"
+ << levelStr << "'";
}
if (Expected<GlobPattern> pat = GlobPattern::create(fields[0])) {
ctx.arg.compressSections.emplace_back(std::move(*pat), type, level);
} else {
- error(arg->getSpelling() + ": " + toString(pat.takeError()));
+ ErrAlways(ctx) << arg->getSpelling() << ": " << toString(pat.takeError());
continue;
}
}
@@ -1636,17 +1650,18 @@ static void readConfigs(Ctx &ctx, opt::InputArgList &args) {
constexpr StringRef errPrefix = "-z dead-reloc-in-nonalloc=: ";
std::pair<StringRef, StringRef> kv = option.second.split('=');
if (kv.first.empty() || kv.second.empty()) {
- error(errPrefix + "expected <section_glob>=<value>");
+ ErrAlways(ctx) << errPrefix << "expected <section_glob>=<value>";
continue;
}
uint64_t v;
if (!to_integer(kv.second, v))
- error(errPrefix + "expected a non-negative integer, but got '" +
- kv.second + "'");
+ ErrAlways(ctx) << errPrefix
+ << "expected a non-negative integer, but got '"
+ << kv.second << "'";
else if (Expected<GlobPattern> pat = GlobPattern::create(kv.first))
ctx.arg.deadRelocInNonAlloc.emplace_back(std::move(*pat), v);
else
- error(errPrefix + toString(pat.takeError()) + ": " + kv.first);
+ ErrAlways(ctx) << errPrefix << pat.takeError() << ": " << kv.first;
}
cl::ResetAllOptionOccurrences();
@@ -1667,8 +1682,8 @@ static void readConfigs(Ctx &ctx, opt::InputArgList &args) {
for (opt::Arg *arg : args.filtered(OPT_plugin_opt_eq)) {
StringRef v(arg->getValue());
if (!v.ends_with("lto-wrapper") && !v.ends_with("lto-wrapper.exe"))
- error(arg->getSpelling() + ": unknown plugin option '" + arg->getValue() +
- "'");
+ ErrAlways(ctx) << arg->getSpelling() << ": unknown plugin option '"
+ << arg->getValue() << "'";
}
ctx.arg.passPlugins = args::getStrings(args, OPT_load_pass_plugins);
@@ -1689,7 +1704,7 @@ static void readConfigs(Ctx &ctx, opt::InputArgList &args) {
else if (s == "default")
ctx.arg.ltoKind = LtoKind::Default;
else
- error("unknown LTO mode: " + s);
+ ErrAlways(ctx) << "unknown LTO mode: " << s;
}
// --threads= takes a positive integer and provides the default value for
@@ -1700,8 +1715,9 @@ static void readConfigs(Ctx &ctx, opt::InputArgList &args) {
StringRef v(arg->getValue());
unsigned threads = 0;
if (!llvm::to_integer(v, threads, 0) || threads == 0)
- error(arg->getSpelling() + ": expected a positive integer, but got '" +
- arg->getValue() + "'");
+ ErrAlways(ctx) << arg->getSpelling()
+ << ": expected a positive integer, but got '"
+ << arg->getValue() << "'";
parallel::strategy = hardware_concurrency(threads);
ctx.arg.thinLTOJobs = v;
} else if (parallel::strategy.compute_thread_count() > 16) {
@@ -1713,20 +1729,22 @@ static void readConfigs(Ctx &ctx, opt::InputArgList &args) {
ctx.arg.threadCount = parallel::strategy.compute_thread_count();
if (ctx.arg.ltoPartitions == 0)
- error("--lto-partitions: number of threads must be > 0");
+ ErrAlways(ctx) << "--lto-partitions: number of threads must be > 0";
if (!get_threadpool_strategy(ctx.arg.thinLTOJobs))
- error("--thinlto-jobs: invalid job count: " + ctx.arg.thinLTOJobs);
+ ErrAlways(ctx) << "--thinlto-jobs: invalid job count: "
+ << ctx.arg.thinLTOJobs;
if (ctx.arg.splitStackAdjustSize < 0)
- error("--split-stack-adjust-size: size must be >= 0");
+ ErrAlways(ctx) << "--split-stack-adjust-size: size must be >= 0";
// The text segment is traditionally the first segment, whose address equals
// the base address. However, lld places the R PT_LOAD first. -Ttext-segment
// is an old-fashioned option that does not play well with lld's layout.
// Suggest --image-base as a likely alternative.
if (args.hasArg(OPT_Ttext_segment))
- error("-Ttext-segment is not supported. Use --image-base if you "
- "intend to set the base address");
+ ErrAlways(ctx)
+ << "-Ttext-segment is not supported. Use --image-base if you "
+ "intend to set the base address";
// Parse ELF{32,64}{LE,BE} and CPU type.
if (auto *arg = args.getLastArg(OPT_m)) {
@@ -1748,7 +1766,7 @@ static void readConfigs(Ctx &ctx, opt::InputArgList &args) {
else if (s == "both")
ctx.arg.sysvHash = ctx.arg.gnuHash = true;
else
- error("unknown --hash-style: " + s);
+ ErrAlways(ctx) << "unknown --hash-style: " << s;
}
if (args.hasArg(OPT_print_map))
@@ -1772,8 +1790,8 @@ static void readConfigs(Ctx &ctx, opt::InputArgList &args) {
if (auto *arg = args.getLastArg(OPT_symbol_ordering_file)){
if (args.hasArg(OPT_call_graph_ordering_file))
- error("--symbol-ordering-file and --call-graph-order-file "
- "may not be used together");
+ ErrAlways(ctx) << "--symbol-ordering-file and --call-graph-order-file "
+ "may not be used together";
if (std::optional<MemoryBufferRef> buffer =
readFile(ctx, arg->getValue())) {
ctx.arg.symbolOrderingFile = getSymbolOrderingFile(ctx, *buffer);
@@ -1805,8 +1823,8 @@ static void readConfigs(Ctx &ctx, opt::InputArgList &args) {
if (Expected<GlobPattern> pat = GlobPattern::create(pattern))
ctx.arg.warnBackrefsExclude.push_back(std::move(*pat));
else
- error(arg->getSpelling() + ": " + toString(pat.takeError()) + ": " +
- pattern);
+ ErrAlways(ctx) << arg->getSpelling() << ": " << pat.takeError() << ": "
+ << pattern;
}
// For -no-pie and -pie, --export-dynamic-symbol specifies defined symbols
@@ -1834,7 +1852,7 @@ static void readConfigs(Ctx &ctx, opt::InputArgList &args) {
if (std::optional<MemoryBufferRef> buffer = readFile(ctx, *path))
readVersionScript(ctx, *buffer);
} else {
- error(Twine("cannot find version script ") + arg->getValue());
+ ErrAlways(ctx) << Twine("cannot find version script ") << arg->getValue();
}
}
@@ -1917,13 +1935,14 @@ static void setConfigs(Ctx &ctx, opt::InputArgList &args) {
{
llvm::TimeTraceScope timeScope("Create output files");
if (auto e = tryCreateFile(ctx.arg.outputFile))
- error("cannot open output file " + ctx.arg.outputFile + ": " +
- e.message());
+ ErrAlways(ctx) << "cannot open output file " << ctx.arg.outputFile << ": "
+ << e.message();
if (auto e = tryCreateFile(ctx.arg.mapFile))
- error("cannot open map file " + ctx.arg.mapFile + ": " + e.message());
+ ErrAlways(ctx) << "cannot open map file " << ctx.arg.mapFile << ": "
+ << e.message();
if (auto e = tryCreateFile(ctx.arg.whyExtract))
- error("cannot open --why-extract= file " + ctx.arg.whyExtract + ": " +
- e.message());
+ ErrAlways(ctx) << "cannot open --why-extract= file " << ctx.arg.whyExtract
+ << ": " << e.message();
}
}
@@ -1932,8 +1951,8 @@ static bool isFormatBinary(StringRef s) {
return true;
if (s == "elf" || s == "default")
return false;
- error("unknown --format value: " + s +
- " (supported formats: elf, default, binary)");
+ ErrAlways(ctx) << "unknown --format value: " << s
+ << " (supported formats: elf, default, binary)";
return false;
}
@@ -1978,7 +1997,7 @@ void LinkerDriver::createFiles(opt::InputArgList &args) {
}
break;
}
- error(Twine("cannot find linker script ") + arg->getValue());
+ ErrAlways(ctx) << Twine("cannot find linker script ") << arg->getValue();
break;
case OPT_as_needed:
ctx.arg.asNeeded = true;
@@ -2012,33 +2031,33 @@ void LinkerDriver::createFiles(opt::InputArgList &args) {
break;
case OPT_in_implib:
if (armCmseImpLib)
- error("multiple CMSE import libraries not supported");
+ ErrAlways(ctx) << "multiple CMSE import libraries not supported";
else if (std::optional<MemoryBufferRef> mb =
readFile(ctx, arg->getValue()))
armCmseImpLib = createObjFile(ctx, *mb);
break;
case OPT_start_group:
if (isInGroup)
- error("nested --start-group");
+ ErrAlways(ctx) << "nested --start-group";
isInGroup = true;
break;
case OPT_end_group:
if (!isInGroup)
- error("stray --end-group");
+ ErrAlways(ctx) << "stray --end-group";
isInGroup = false;
++nextGroupId;
break;
case OPT_start_lib:
if (inLib)
- error("nested --start-lib");
+ ErrAlways(ctx) << "nested --start-lib";
if (isInGroup)
- error("may not nest --start-lib in --start-group");
+ ErrAlways(ctx) << "may not nest --start-lib in --start-group";
inLib = true;
isInGroup = true;
break;
case OPT_end_lib:
if (!inLib)
- error("stray --end-lib");
+ ErrAlways(ctx) << "stray --end-lib";
inLib = false;
isInGroup = false;
++nextGroupId;
@@ -2048,7 +2067,7 @@ void LinkerDriver::createFiles(opt::InputArgList &args) {
break;
case OPT_pop_state:
if (stack.empty()) {
- error("unbalanced --push-state/--pop-state");
+ ErrAlways(ctx) << "unbalanced --push-state/--pop-state";
break;
}
std::tie(ctx.arg.asNeeded, ctx.arg.isStatic, inWholeArchive) =
@@ -2061,7 +2080,7 @@ void LinkerDriver::createFiles(opt::InputArgList &args) {
if (defaultScript && !hasScript)
readLinkerScript(ctx, *defaultScript);
if (files.empty() && !hasInput && errorCount() == 0)
- error("no input files");
+ ErrAlways(ctx) << "no input files";
}
// If -m <machine_type> was not given, infer it from object files.
@@ -2084,7 +2103,8 @@ void LinkerDriver::inferMachineType() {
return;
}
if (!inferred)
- error("target emulation unknown: -m or at least one .o file required");
+ ErrAlways(ctx)
+ << "target emulation unknown: -m or at least one .o file required";
}
// Parse -z max-page-size=<value>. The default value is defined by
@@ -2093,7 +2113,7 @@ static uint64_t getMaxPageSize(Ctx &ctx, opt::InputArgList &args) {
uint64_t val = args::getZOptionValue(args, OPT_z, "max-page-size",
ctx.target->defaultMaxPageSize);
if (!isPowerOf2_64(val)) {
- error("max-page-size: value isn't a power of 2");
+ ErrAlways(ctx) << "max-page-size: value isn't a power of 2";
return ctx.target->defaultMaxPageSize;
}
if (ctx.arg.nmagic || ctx.arg.omagic) {
@@ -2110,7 +2130,7 @@ static uint64_t getCommonPageSize(Ctx &ctx, opt::InputArgList &args) {
uint64_t val = args::getZOptionValue(args, OPT_z, "common-page-size",
ctx.target->defaultCommonPageSize);
if (!isPowerOf2_64(val)) {
- error("common-page-size: value isn't a power of 2");
+ ErrAlways(ctx) << "common-page-size: value isn't a power of 2";
return ctx.target->defaultCommonPageSize;
}
if (ctx.arg.nmagic || ctx.arg.omagic) {
@@ -2135,7 +2155,7 @@ static std::optional<uint64_t> getImageBase(Ctx &ctx, opt::InputArgList &args) {
StringRef s = arg->getValue();
uint64_t v;
if (!to_integer(s, v)) {
- error("--image-base: number expected, but got " + s);
+ ErrAlways(ctx) << "--image-base: number expected, but got " << s;
return 0;
}
if ((v % ctx.arg.maxPageSize) != 0)
@@ -2209,7 +2229,7 @@ static void handleUndefined(Ctx &ctx, Symbol *sym, const char *option) {
static void handleUndefinedGlob(Ctx &ctx, StringRef arg) {
Expected<GlobPattern> pat = GlobPattern::create(arg);
if (!pat) {
- error("--undefined-glob: " + toString(pat.takeError()) + ": " + arg);
+ ErrAlways(ctx) << "--undefined-glob: " << pat.takeError() << ": " << arg;
return;
}
@@ -2240,8 +2260,8 @@ static void writeArchiveStats(Ctx &ctx) {
std::error_code ec;
raw_fd_ostream os = ctx.openAuxiliaryFile(ctx.arg.printArchiveStats, ec);
if (ec) {
- error("--print-archive-stats=: cannot open " + ctx.arg.printArchiveStats +
- ": " + ec.message());
+ ErrAlways(ctx) << "--print-archive-stats=: cannot open "
+ << ctx.arg.printArchiveStats << ": " << ec.message();
return;
}
@@ -2270,8 +2290,8 @@ static void writeWhyExtract(Ctx &ctx) {
std::error_code ec;
raw_fd_ostream os = ctx.openAuxiliaryFile(ctx.arg.whyExtract, ec);
if (ec) {
- error("cannot open --why-extract= file " + ctx.arg.whyExtract + ": " +
- ec.message());
+ ErrAlways(ctx) << "cannot open --why-extract= file " << ctx.arg.whyExtract
+ << ": " << ec.message();
return;
}
@@ -2329,7 +2349,8 @@ static void writeDependencyFile(Ctx &ctx) {
std::error_code ec;
raw_fd_ostream os = ctx.openAuxiliaryFile(ctx.arg.dependencyFile, ec);
if (ec) {
- error("cannot open " + ctx.arg.dependencyFile + ": " + ec.message());
+ ErrAlways(ctx) << "cannot open " << ctx.arg.dependencyFile << ": "
+ << ec.message();
return;
}
@@ -2492,16 +2513,17 @@ static void readSymbolPartitionSection(Ctx &ctx, InputSectionBase *s) {
// from being used together with various linker features that assume a single
// set of output sections.
if (ctx.script->hasSectionsCommand)
- error(toString(s->file) +
- ": partitions cannot be used with the SECTIONS command");
+ ErrAlways(ctx) << s->file
+ << ": partitions cannot be used with the SECTIONS command";
if (ctx.script->hasPhdrsCommands())
- error(toString(s->file) +
- ": partitions cannot be used with the PHDRS command");
+ ErrAlways(ctx) << s->file
+ << ": partitions cannot be used with the PHDRS command";
if (!ctx.arg.sectionStartMap.empty())
- error(toString(s->file) + ": partitions cannot be used with "
- "--section-start, -Ttext, -Tdata or -Tbss");
+ ErrAlways(ctx) << s->file
+ << ": partitions cannot be used with "
+ "--section-start, -Ttext, -Tdata or -Tbss";
if (ctx.arg.emachine == EM_MIPS)
- error(toString(s->file) + ": partitions cannot be used on this target");
+ ErrAlways(ctx) << s->file << ": partitions cannot be used on this target";
// Impose a limit of no more than 254 partitions. This limit comes from the
// sizes of the Partition fields in InputSectionBase and Symbol, as well as
@@ -2725,7 +2747,7 @@ static void redirectSymbols(Ctx &ctx, ArrayRef<WrappedSymbol> wrapped) {
static void reportMissingFeature(StringRef config, const Twine &report) {
if (config == "error")
- error(report);
+ ErrAlways(ctx) << report;
else if (config == "warning")
warn(report);
}
diff --git a/lld/ELF/DriverUtils.cpp b/lld/ELF/DriverUtils.cpp
index cd7688ee3f80c0..096f033a767ef5 100644
--- a/lld/ELF/DriverUtils.cpp
+++ b/lld/ELF/DriverUtils.cpp
@@ -62,14 +62,14 @@ static void handleColorDiagnostics(opt::InputArgList &args) {
else if (s == "never")
lld::errs().enable_colors(false);
else if (s != "auto")
- error("unknown option: --color-diagnostics=" + s);
+ ErrAlways(ctx) << "unknown option: --color-diagnostics=" << s;
}
static cl::TokenizerCallback getQuotingStyle(opt::InputArgList &args) {
if (auto *arg = args.getLastArg(OPT_rsp_quoting)) {
StringRef s = arg->getValue();
if (s != "windows" && s != "posix")
- error("invalid response file quoting: " + s);
+ ErrAlways(ctx) << "invalid response file quoting: " << s;
if (s == "windows")
return cl::TokenizeWindowsCommandLine;
return cl::TokenizeGNUCommandLine;
@@ -122,15 +122,16 @@ opt::InputArgList ELFOptTable::parse(ArrayRef<const char *> argv) {
handleColorDiagnostics(args);
if (missingCount)
- error(Twine(args.getArgString(missingIndex)) + ": missing argument");
+ ErrAlways(ctx) << Twine(args.getArgString(missingIndex))
+ << ": missing argument";
for (opt::Arg *arg : args.filtered(OPT_UNKNOWN)) {
std::string nearest;
if (findNearest(arg->getAsString(args), nearest) > 1)
- error("unknown argument '" + arg->getAsString(args) + "'");
+ ErrAlways(ctx) << "unknown argument '" << arg->getAsString(args) << "'";
else
- error("unknown argument '" + arg->getAsString(args) +
- "', did you mean '" + nearest + "'");
+ ErrAlways(ctx) << "unknown argument '" << arg->getAsString(args)
+ << "', did you mean '" << nearest << "'";
}
return args;
}
diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp
index f9bf90bdc0a6a2..4c440cebc37f12 100644
--- a/lld/ELF/InputFiles.cpp
+++ b/lld/ELF/InputFiles.cpp
@@ -133,12 +133,13 @@ static void updateARMVFPArgs(Ctx &ctx, const ARMAttributeParser &attributes,
// Object compatible with all conventions.
return;
default:
- error(toString(f) + ": unknown Tag_ABI_VFP_args value: " + Twine(vfpArgs));
+ ErrAlways(ctx) << f
+ << ": unknown Tag_ABI_VFP_args value: " << Twine(vfpArgs);
return;
}
// Follow ld.bfd and error if there is a mix of calling conventions.
if (ctx.arg.armVFPArgs != arg && ctx.arg.armVFPArgs != ARMVFPArgKind::Default)
- error(toString(f) + ": incompatible Tag_ABI_VFP_args");
+ ErrAlways(ctx) << f << ": incompatible Tag_ABI_VFP_args";
else
ctx.arg.armVFPArgs = arg;
}
@@ -252,7 +253,7 @@ std::optional<MemoryBufferRef> elf::readFile(Ctx &ctx, StringRef path) {
auto mbOrErr = MemoryBuffer::getFile(path, /*IsText=*/false,
/*RequiresNullTerminator=*/false);
if (auto ec = mbOrErr.getError()) {
- error("cannot open " + path + ": " + ec.message());
+ ErrAlways(ctx) << "cannot open " << path << ": " << ec.message();
return std::nullopt;
}
@@ -281,7 +282,7 @@ static bool isCompatible(Ctx &ctx, InputFile *file) {
StringRef target =
!ctx.arg.bfdname.empty() ? ctx.arg.bfdname : ctx.arg.emulation;
if (!target.empty()) {
- error(toString(file) + " is incompatible with " + target);
+ ErrAlways(ctx) << file << " is incompatible with " << target;
return false;
}
@@ -295,7 +296,7 @@ static bool isCompatible(Ctx &ctx, InputFile *file) {
std::string with;
if (existing)
with = " with " + toString(existing);
- error(toString(file) + " is incompatible" + with);
+ ErrAlways(ctx) << file << " is incompatible" << with;
return false;
}
@@ -432,9 +433,9 @@ static void addDependentLibrary(Ctx &ctx, StringRef specifier,
else if (fs::exists(specifier))
ctx.driver.addFile(specifier, /*withLOption=*/false);
else
- error(toString(f) +
- ": unable to find library from dependent library specifier: " +
- specifier);
+ ErrAlways(ctx)
+ << f << ": unable to find library from dependent library specifier: "
+ << specifier;
}
// Record the membership of a section group so that in the garbage collection
@@ -608,10 +609,10 @@ template <class ELFT> void ObjFile<ELFT>::parse(bool ignoreComdats) {
ArrayRef<char> data = CHECK(
this->getObj().template getSectionContentsAsArray<char>(sec), this);
if (!data.empty() && data.back() != '\0') {
- error(
- toString(this) +
- ": corrupted dependent libraries section (unterminated string): " +
- name);
+ ErrAlways(ctx)
+ << this
+ << ": corrupted dependent libraries section (unterminated string): "
+ << name;
} else {
for (const char *d = data.begin(), *e = data.end(); d < e;) {
StringRef s(d);
@@ -904,9 +905,9 @@ void ObjFile<ELFT>::initializeSections(bool ignoreComdats,
}
if (s->relSecIdx != 0)
- error(
- toString(s) +
- ": multiple relocation sections to one section are not supported");
+ ErrAlways(ctx) << s
+ << ": multiple relocation sections to one section are "
+ "not supported";
s->relSecIdx = i;
// Relocation sections are usually removed from the output, so return
@@ -940,9 +941,10 @@ void ObjFile<ELFT>::initializeSections(bool ignoreComdats,
InputSection *isec = cast<InputSection>(this->sections[i]);
linkSec->dependentSections.push_back(isec);
if (!isa<InputSection>(linkSec))
- error("a section " + isec->name +
- " with SHF_LINK_ORDER should not refer a non-regular section: " +
- toString(linkSec));
+ ErrAlways(ctx)
+ << "a section " << isec->name
+ << " with SHF_LINK_ORDER should not refer a non-regular section: "
+ << linkSec;
}
for (ArrayRef<Elf_Word> entries : selectedGroups)
@@ -1040,8 +1042,8 @@ InputSectionBase *ObjFile<ELFT>::getRelocTarget(uint32_t idx, uint32_t info) {
return target;
}
- error(toString(this) + Twine(": relocation section (index ") + Twine(idx) +
- ") has invalid sh_info (" + Twine(info) + ")");
+ ErrAlways(ctx) << this << Twine(": relocation section (index ") << Twine(idx)
+ << ") has invalid sh_info (" << Twine(info) << ")";
return nullptr;
}
@@ -1087,8 +1089,8 @@ InputSectionBase *ObjFile<ELFT>::createInputSection(uint32_t idx,
// for split stack will include a .note.GNU-split-stack section.
if (name == ".note.GNU-split-stack") {
if (ctx.arg.relocatable) {
- error(
- "cannot mix split-stack and non-split-stack in a relocatable link");
+ ErrAlways(ctx) << "cannot mix split-stack and non-split-stack in a "
+ "relocatable link";
return &InputSection::discarded;
}
this->splitStack = true;
@@ -1209,8 +1211,9 @@ void ObjFile<ELFT>::initSectionsAndLocalSyms(bool ignoreComdats) {
if (LLVM_UNLIKELY(secIdx >= sections.size()))
Fatal(ctx) << this << ": invalid section index: " << Twine(secIdx);
if (LLVM_UNLIKELY(eSym.getBinding() != STB_LOCAL))
- error(toString(this) + ": non-local symbol (" + Twine(i) +
- ") found at index < .symtab's sh_info (" + Twine(end) + ")");
+ ErrAlways(ctx) << this << ": non-local symbol (" << Twine(i)
+ << ") found at index < .symtab's sh_info (" << Twine(end)
+ << ")";
InputSectionBase *sec = sections[secIdx];
uint8_t type = eSym.getType();
@@ -1492,7 +1495,7 @@ template <class ELFT> void SharedFile::parse() {
}
if (versymSec && numELFSyms == 0) {
- error("SHT_GNU_versym should be associated with symbol table");
+ ErrAlways(ctx) << "SHT_GNU_versym should be associated with symbol table";
return;
}
@@ -1571,9 +1574,9 @@ template <class ELFT> void SharedFile::parse() {
// as of binutils 2.34, GNU ld produces VER_NDX_LOCAL.
if (ver != VER_NDX_LOCAL && ver != VER_NDX_GLOBAL) {
if (idx >= verneeds.size()) {
- error("corrupt input file: version need index " + Twine(idx) +
- " for symbol " + name + " is out of bounds\n>>> defined in " +
- toString(this));
+ ErrAlways(ctx) << "corrupt input file: version need index "
+ << Twine(idx) << " for symbol " << name
+ << " is out of bounds\n>>> defined in " << this;
continue;
}
StringRef verName = stringTable.data() + verneeds[idx];
@@ -1597,9 +1600,9 @@ template <class ELFT> void SharedFile::parse() {
// VER_NDX_LOCAL. Workaround this bug.
if (ctx.arg.emachine == EM_MIPS && name == "_gp_disp")
continue;
- error("corrupt input file: version definition index " + Twine(idx) +
- " for symbol " + name + " is out of bounds\n>>> defined in " +
- toString(this));
+ ErrAlways(ctx) << "corrupt input file: version definition index "
+ << Twine(idx) << " for symbol " << name
+ << " is out of bounds\n>>> defined in " << this;
continue;
}
@@ -1683,8 +1686,9 @@ static uint16_t getBitcodeMachineKind(StringRef path, const Triple &t) {
case Triple::x86_64:
return EM_X86_64;
default:
- error(path + ": could not infer e_machine from bitcode target triple " +
- t.str());
+ ErrAlways(ctx) << path
+ << ": could not infer e_machine from bitcode target triple "
+ << t.str();
return EM_NONE;
}
}
diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp
index f4a5304d4f251f..92bbc977a20a0b 100644
--- a/lld/ELF/InputSection.cpp
+++ b/lld/ELF/InputSection.cpp
@@ -64,7 +64,7 @@ InputSectionBase::InputSectionBase(InputFile *file, uint64_t flags,
// sections are smaller than 4 GiB, which is not an unreasonable
// assumption as of 2017.
if (sectionKind == SectionBase::Merge && content().size() > UINT32_MAX)
- error(toString(this) + ": section too large");
+ ErrAlways(ctx) << this << ": section too large";
// The ELF spec states that a value of 0 means the section has
// no alignment constraints.
@@ -256,22 +256,24 @@ template <typename ELFT> void InputSectionBase::parseCompressedHeader() {
// New-style header
if (content().size() < sizeof(typename ELFT::Chdr)) {
- error(toString(this) + ": corrupted compressed section");
+ ErrAlways(ctx) << this << ": corrupted compressed section";
return;
}
auto *hdr = reinterpret_cast<const typename ELFT::Chdr *>(content().data());
if (hdr->ch_type == ELFCOMPRESS_ZLIB) {
if (!compression::zlib::isAvailable())
- error(toString(this) + " is compressed with ELFCOMPRESS_ZLIB, but lld is "
- "not built with zlib support");
+ ErrAlways(ctx) << this
+ << " is compressed with ELFCOMPRESS_ZLIB, but lld is "
+ "not built with zlib support";
} else if (hdr->ch_type == ELFCOMPRESS_ZSTD) {
if (!compression::zstd::isAvailable())
- error(toString(this) + " is compressed with ELFCOMPRESS_ZSTD, but lld is "
- "not built with zstd support");
+ ErrAlways(ctx) << this
+ << " is compressed with ELFCOMPRESS_ZSTD, but lld is "
+ "not built with zstd support";
} else {
- error(toString(this) + ": unsupported compression type (" +
- Twine(hdr->ch_type) + ")");
+ ErrAlways(ctx) << this << ": unsupported compression type ("
+ << Twine(hdr->ch_type) << ")";
return;
}
@@ -1157,8 +1159,8 @@ static void switchMorestackCallsToMorestackNonSplit(
// __morestack_non_split.
Symbol *moreStackNonSplit = ctx.symtab->find("__morestack_non_split");
if (!moreStackNonSplit) {
- error("mixing split-stack objects requires a definition of "
- "__morestack_non_split");
+ ErrAlways(ctx) << "mixing split-stack objects requires a definition of "
+ "__morestack_non_split";
return;
}
@@ -1235,9 +1237,10 @@ void InputSectionBase::adjustSplitStackFunctionPrologues(Ctx &ctx, uint8_t *buf,
f->stOther))
continue;
if (!getFile<ELFT>()->someNoSplitStack)
- error(lld::toString(this) + ": " + f->getName() +
- " (with -fsplit-stack) calls " + rel.sym->getName() +
- " (without -fsplit-stack), but couldn't adjust its prologue");
+ ErrAlways(ctx)
+ << lld::toString(this) << ": " << f->getName()
+ << " (with -fsplit-stack) calls " << rel.sym->getName()
+ << " (without -fsplit-stack), but couldn't adjust its prologue";
}
}
diff --git a/lld/ELF/LTO.cpp b/lld/ELF/LTO.cpp
index aef058286cea0d..7214b7f2ae4904 100644
--- a/lld/ELF/LTO.cpp
+++ b/lld/ELF/LTO.cpp
@@ -78,8 +78,8 @@ static lto::Config createConfig(Ctx &ctx) {
ErrorOr<std::unique_ptr<MemoryBuffer>> MBOrErr =
MemoryBuffer::getFile(ctx.arg.ltoBasicBlockSections.str());
if (!MBOrErr) {
- error("cannot open " + ctx.arg.ltoBasicBlockSections + ":" +
- MBOrErr.getError().message());
+ ErrAlways(ctx) << "cannot open " << ctx.arg.ltoBasicBlockSections << ":"
+ << MBOrErr.getError().message();
} else {
c.Options.BBSectionsFuncListBuf = std::move(*MBOrErr);
}
diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp
index d2088b4c648180..72c876fe716552 100644
--- a/lld/ELF/LinkerScript.cpp
+++ b/lld/ELF/LinkerScript.cpp
@@ -309,7 +309,8 @@ void LinkerScript::processInsertCommands() {
SmallVector<OutputDesc *, 0> moves;
for (const InsertCommand &cmd : insertCommands) {
if (ctx.arg.enableNonContiguousRegions)
- error("INSERT cannot be used with --enable-non-contiguous-regions");
+ ErrAlways(ctx)
+ << "INSERT cannot be used with --enable-non-contiguous-regions";
for (StringRef name : cmd.names) {
// If base is empty, it may have been discarded by
@@ -330,8 +331,8 @@ void LinkerScript::processInsertCommands() {
return to != nullptr && to->osec.name == cmd.where;
});
if (insertPos == sectionCommands.end()) {
- error("unable to insert " + cmd.names[0] +
- (cmd.isAfter ? " after " : " before ") + cmd.where);
+ ErrAlways(ctx) << "unable to insert " << cmd.names[0]
+ << (cmd.isAfter ? " after " : " before ") << cmd.where;
} else {
if (cmd.isAfter)
++insertPos;
@@ -652,7 +653,7 @@ LinkerScript::computeInputSections(const InputSectionDescription *cmd,
void LinkerScript::discard(InputSectionBase &s) {
if (&s == ctx.in.shStrTab.get())
- error("discarding " + s.name + " section is not allowed");
+ ErrAlways(ctx) << "discarding " << s.name << " section is not allowed";
s.markDead();
s.parent = nullptr;
@@ -737,8 +738,8 @@ void LinkerScript::processSectionCommands() {
// Process OVERWRITE_SECTIONS first so that it can overwrite the main script
// or orphans.
if (ctx.arg.enableNonContiguousRegions && !overwriteSections.empty())
- error("OVERWRITE_SECTIONS cannot be used with "
- "--enable-non-contiguous-regions");
+ ErrAlways(ctx) << "OVERWRITE_SECTIONS cannot be used with "
+ "--enable-non-contiguous-regions";
DenseMap<CachedHashStringRef, OutputDesc *> map;
size_t i = 0;
for (OutputDesc *osd : overwriteSections) {
@@ -1052,7 +1053,7 @@ void LinkerScript::diagnoseOrphanHandling() const {
StringRef name = getOutputSectionName(sec);
if (ctx.arg.orphanHandling == OrphanHandlingPolicy::Error)
- error(toString(sec) + " is being placed in '" + name + "'");
+ ErrAlways(ctx) << sec << " is being placed in '" << name << "'";
else
warn(toString(sec) + " is being placed in '" + name + "'");
}
@@ -1064,7 +1065,8 @@ void LinkerScript::diagnoseMissingSGSectionAddress() const {
OutputSection *sec = findByName(sectionCommands, ".gnu.sgstubs");
if (sec && !sec->addrExpr && !ctx.arg.sectionStartMap.count(".gnu.sgstubs"))
- error("no address assigned to the veneers output section " + sec->name);
+ ErrAlways(ctx) << "no address assigned to the veneers output section "
+ << sec->name;
}
// This function searches for a memory region to place the given output
@@ -1092,7 +1094,8 @@ LinkerScript::findMemoryRegion(OutputSection *sec, MemoryRegion *hint) {
if (!sec->memoryRegionName.empty()) {
if (MemoryRegion *m = memoryRegions.lookup(sec->memoryRegionName))
return {m, m};
- error("memory region '" + sec->memoryRegionName + "' not declared");
+ ErrAlways(ctx) << "memory region '" << sec->memoryRegionName
+ << "' not declared";
return {nullptr, nullptr};
}
@@ -1114,7 +1117,8 @@ LinkerScript::findMemoryRegion(OutputSection *sec, MemoryRegion *hint) {
}
// Otherwise, no suitable region was found.
- error("no memory region specified for section '" + sec->name + "'");
+ ErrAlways(ctx) << "no memory region specified for section '" << sec->name
+ << "'";
return {nullptr, nullptr};
}
@@ -1396,7 +1400,8 @@ void LinkerScript::adjustSectionsAfterSorting() {
if (MemoryRegion *m = memoryRegions.lookup(sec->lmaRegionName))
sec->lmaRegion = m;
else
- error("memory region '" + sec->lmaRegionName + "' not declared");
+ ErrAlways(ctx) << "memory region '" << sec->lmaRegionName
+ << "' not declared";
}
std::tie(sec->memRegion, hint) = findMemoryRegion(sec, hint);
}
@@ -1462,7 +1467,7 @@ void LinkerScript::allocateHeaders(SmallVector<PhdrEntry *, 0> &phdrs) {
// Error if we were explicitly asked to allocate headers.
if (hasExplicitHeaders)
- error("could not allocate headers");
+ ErrAlways(ctx) << "could not allocate headers";
ctx.out.elfHeader->ptLoad = nullptr;
ctx.out.programHeaders->ptLoad = nullptr;
@@ -1682,7 +1687,7 @@ ExprValue LinkerScript::getSymbolValue(StringRef name, const Twine &loc) {
if (name == ".") {
if (state)
return {state->outSec, false, dot - state->outSec->addr, loc};
- error(loc + ": unable to get location counter value");
+ ErrAlways(ctx) << loc << ": unable to get location counter value";
return 0;
}
@@ -1700,7 +1705,7 @@ ExprValue LinkerScript::getSymbolValue(StringRef name, const Twine &loc) {
return {nullptr, false, 0, loc};
}
- error(loc + ": symbol not found: " + name);
+ ErrAlways(ctx) << loc << ": symbol not found: " << name;
return 0;
}
@@ -1722,8 +1727,8 @@ SmallVector<size_t, 0> LinkerScript::getPhdrIndices(OutputSection *cmd) {
if (std::optional<size_t> idx = getPhdrIndex(phdrsCommands, s))
ret.push_back(*idx);
else if (s != "NONE")
- error(cmd->location + ": program header '" + s +
- "' is not listed in PHDRS");
+ ErrAlways(ctx) << cmd->location << ": program header '" << s
+ << "' is not listed in PHDRS";
}
return ret;
}
@@ -1765,9 +1770,9 @@ static void checkMemoryRegion(const MemoryRegion *region,
uint64_t osecEnd = addr + osec->size;
uint64_t regionEnd = region->getOrigin() + region->getLength();
if (osecEnd > regionEnd) {
- error("section '" + osec->name + "' will not fit in region '" +
- region->name + "': overflowed by " + Twine(osecEnd - regionEnd) +
- " bytes");
+ ErrAlways(ctx) << "section '" << osec->name << "' will not fit in region '"
+ << region->name << "': overflowed by "
+ << Twine(osecEnd - regionEnd) << " bytes";
}
}
diff --git a/lld/ELF/MapFile.cpp b/lld/ELF/MapFile.cpp
index afaf04dc72fe6c..caf386ad2d6278 100644
--- a/lld/ELF/MapFile.cpp
+++ b/lld/ELF/MapFile.cpp
@@ -268,7 +268,7 @@ void elf::writeMapAndCref(Ctx &ctx) {
StringRef mapFile = ctx.arg.mapFile.empty() ? "-" : ctx.arg.mapFile;
raw_fd_ostream os = ctx.openAuxiliaryFile(mapFile, ec);
if (ec) {
- error("cannot open " + mapFile + ": " + ec.message());
+ ErrAlways(ctx) << "cannot open " << mapFile << ": " << ec.message();
return;
}
diff --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp
index 6cae7cf8f8599d..fb4d7130b765bf 100644
--- a/lld/ELF/OutputSections.cpp
+++ b/lld/ELF/OutputSections.cpp
@@ -151,9 +151,10 @@ void OutputSection::commitSection(InputSection *isec) {
} else {
// Otherwise, check if new type or flags are compatible with existing ones.
if ((flags ^ isec->flags) & SHF_TLS)
- error("incompatible section flags for " + name + "\n>>> " +
- toString(isec) + ": 0x" + utohexstr(isec->flags) +
- "\n>>> output section " + name + ": 0x" + utohexstr(flags));
+ ErrAlways(ctx) << "incompatible section flags for " << name << "\n>>> "
+ << isec << ": 0x" << utohexstr(isec->flags)
+ << "\n>>> output section " << name << ": 0x"
+ << utohexstr(flags);
}
isec->parent = this;
diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp
index 6553ff9b06bb1e..88e742585673d6 100644
--- a/lld/ELF/Relocations.cpp
+++ b/lld/ELF/Relocations.cpp
@@ -1042,8 +1042,9 @@ bool RelocationScanner::isStaticLinkTimeConstant(RelExpr e, RelType type,
if (sym.scriptDefined)
return true;
- error("relocation " + toString(type) + " cannot refer to absolute symbol: " +
- toString(sym) + getLocation(ctx, *sec, sym, relOff));
+ Err(ctx) << "relocation " << type
+ << " cannot refer to absolute symbol: " << &sym
+ << getLocation(ctx, *sec, sym, relOff);
return true;
}
@@ -1218,10 +1219,9 @@ void RelocationScanner::processAux(RelExpr expr, RelType type, uint64_t offset,
// Produce a copy relocation.
if (auto *ss = dyn_cast<SharedSymbol>(&sym)) {
if (!ctx.arg.zCopyreloc)
- error("unresolvable relocation " + toString(type) +
- " against symbol '" + toString(*ss) +
- "'; recompile with -fPIC or remove '-z nocopyreloc'" +
- getLocation(ctx, *sec, sym, offset));
+ Err(ctx) << "unresolvable relocation " << type << " against symbol '"
+ << ss << "'; recompile with -fPIC or remove '-z nocopyreloc'"
+ << getLocation(ctx, *sec, sym, offset);
sym.setFlags(NEEDS_COPY);
}
sec->addReloc({expr, type, offset, addend, &sym});
diff --git a/lld/ELF/ScriptLexer.cpp b/lld/ELF/ScriptLexer.cpp
index 7b45e26ee405e0..a89db24e27d039 100644
--- a/lld/ELF/ScriptLexer.cpp
+++ b/lld/ELF/ScriptLexer.cpp
@@ -87,7 +87,7 @@ void ScriptLexer::setError(const Twine &msg) {
if (prevTok.size())
s += "\n>>> " + getLine().str() + "\n>>> " +
std::string(getColumnNumber(), ' ') + "^";
- error(s);
+ ErrAlways(ctx) << s;
}
void ScriptLexer::lex() {
@@ -116,7 +116,8 @@ void ScriptLexer::lex() {
if (e == StringRef::npos) {
size_t lineno =
StringRef(curBuf.begin, s.data() - curBuf.begin).count('\n');
- error(curBuf.filename + ":" + Twine(lineno + 1) + ": unclosed quote");
+ ErrAlways(ctx) << curBuf.filename << ":" << Twine(lineno + 1)
+ << ": unclosed quote";
return;
}
diff --git a/lld/ELF/ScriptParser.cpp b/lld/ELF/ScriptParser.cpp
index 3febcfb87da4ac..472605fd294be2 100644
--- a/lld/ELF/ScriptParser.cpp
+++ b/lld/ELF/ScriptParser.cpp
@@ -975,7 +975,7 @@ static Expr checkAlignment(Expr e, std::string &loc) {
return [=] {
uint64_t alignment = std::max((uint64_t)1, e().getValue());
if (!isPowerOf2_64(alignment)) {
- error(loc + ": alignment must be power of 2");
+ ErrAlways(ctx) << loc << ": alignment must be power of 2";
return (uint64_t)1; // Return a dummy value.
}
return alignment;
@@ -1081,7 +1081,7 @@ OutputDesc *ScriptParser::readOutputSectionDescription(StringRef outSec) {
}
if (osec->lmaExpr && !osec->lmaRegionName.empty())
- error("section can't have both LMA and a load region");
+ ErrAlways(ctx) << "section can't have both LMA and a load region";
osec->phdrs = readOutputSectionPhdrs();
@@ -1196,7 +1196,7 @@ SymbolAssignment *ScriptParser::readSymbolAssignment(StringRef name) {
Expr e = readExpr();
if (op != "=") {
std::string loc = getCurrentLocation();
- e = [=, s = ctx.script, c = op[0]]() -> ExprValue {
+ e = [=, s = ctx.script, c = op[0], &ctx = ctx]() -> ExprValue {
ExprValue lhs = s->getSymbolValue(name, loc);
switch (c) {
case '*':
@@ -1204,7 +1204,7 @@ SymbolAssignment *ScriptParser::readSymbolAssignment(StringRef name) {
case '/':
if (uint64_t rv = e().getValue())
return lhs.getValue() / rv;
- error(loc + ": division by zero");
+ ErrAlways(ctx) << loc << ": division by zero";
return 0;
case '+':
return add(*s, lhs, e());
@@ -1248,19 +1248,19 @@ Expr ScriptParser::combine(StringRef op, Expr l, Expr r) {
return [=] { return l().getValue() * r().getValue(); };
if (op == "/") {
std::string loc = getCurrentLocation();
- return [=]() -> uint64_t {
+ return [=, &ctx = ctx]() -> uint64_t {
if (uint64_t rv = r().getValue())
return l().getValue() / rv;
- error(loc + ": division by zero");
+ ErrAlways(ctx) << loc << ": division by zero";
return 0;
};
}
if (op == "%") {
std::string loc = getCurrentLocation();
- return [=]() -> uint64_t {
+ return [=, &ctx = ctx]() -> uint64_t {
if (uint64_t rv = r().getValue())
return l().getValue() % rv;
- error(loc + ": modulo by zero");
+ ErrAlways(ctx) << loc << ": modulo by zero";
return 0;
};
}
@@ -1327,7 +1327,7 @@ Expr ScriptParser::getPageSize() {
return [=, &ctx = this->ctx]() -> uint64_t {
if (ctx.target)
return ctx.arg.commonPageSize;
- error(location + ": unable to calculate page size");
+ ErrAlways(ctx) << location << ": unable to calculate page size";
return 4096; // Return a dummy value.
};
}
diff --git a/lld/ELF/Symbols.cpp b/lld/ELF/Symbols.cpp
index 40f54ea7a2507b..fc3a5115673079 100644
--- a/lld/ELF/Symbols.cpp
+++ b/lld/ELF/Symbols.cpp
@@ -248,8 +248,8 @@ void Symbol::parseSymbolVersion(Ctx &ctx) {
// if the symbol has a local version as it won't be in the dynamic
// symbol table.
if (ctx.arg.shared && versionId != VER_NDX_LOCAL)
- error(toString(file) + ": symbol " + s + " has undefined version " +
- verstr);
+ ErrAlways(ctx) << file << ": symbol " << s << " has undefined version "
+ << verstr;
}
void Symbol::extract(Ctx &ctx) const {
diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp
index 745112164edd6f..6c7abdc7bff547 100644
--- a/lld/ELF/SyntheticSections.cpp
+++ b/lld/ELF/SyntheticSections.cpp
@@ -125,15 +125,17 @@ MipsAbiFlagsSection<ELFT>::create(Ctx &ctx) {
// .MIPS.abiflags instead of merging. To allow for this case (or potential
// zero padding) we ignore everything after the first Elf_Mips_ABIFlags
if (size < sizeof(Elf_Mips_ABIFlags)) {
- error(filename + ": invalid size of .MIPS.abiflags section: got " +
- Twine(size) + " instead of " + Twine(sizeof(Elf_Mips_ABIFlags)));
+ ErrAlways(ctx) << filename
+ << ": invalid size of .MIPS.abiflags section: got "
+ << Twine(size) << " instead of "
+ << Twine(sizeof(Elf_Mips_ABIFlags));
return nullptr;
}
auto *s =
reinterpret_cast<const Elf_Mips_ABIFlags *>(sec->content().data());
if (s->version != 0) {
- error(filename + ": unexpected .MIPS.abiflags version " +
- Twine(s->version));
+ ErrAlways(ctx) << filename << ": unexpected .MIPS.abiflags version "
+ << Twine(s->version);
return nullptr;
}
@@ -198,7 +200,7 @@ MipsOptionsSection<ELFT>::create(Ctx &ctx) {
while (!d.empty()) {
if (d.size() < sizeof(Elf_Mips_Options)) {
- error(filename + ": invalid size of .MIPS.options section");
+ ErrAlways(ctx) << filename << ": invalid size of .MIPS.options section";
break;
}
@@ -252,7 +254,7 @@ MipsReginfoSection<ELFT>::create(Ctx &ctx) {
sec->markDead();
if (sec->content().size() != sizeof(Elf_Mips_RegInfo)) {
- error(toString(sec->file) + ": invalid size of .reginfo section");
+ ErrAlways(ctx) << sec->file << ": invalid size of .reginfo section";
return nullptr;
}
@@ -4392,7 +4394,7 @@ static uint8_t getAbiVersion(Ctx &ctx) {
uint8_t ver = ctx.objectFiles[0]->abiVersion;
for (InputFile *file : ArrayRef(ctx.objectFiles).slice(1))
if (file->abiVersion != ver)
- error("incompatible ABI version: " + toString(file));
+ ErrAlways(ctx) << "incompatible ABI version: " << file;
return ver;
}
diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp
index 12d51b828710d2..1a6ac7bfa15aa2 100644
--- a/lld/ELF/Writer.cpp
+++ b/lld/ELF/Writer.cpp
@@ -202,8 +202,8 @@ void elf::addReservedSymbols(Ctx &ctx) {
if (Symbol *s = ctx.symtab->find(gotSymName)) {
if (s->isDefined()) {
- error(toString(s->file) + " cannot redefine linker defined symbol '" +
- gotSymName + "'");
+ ErrAlways(ctx) << s->file << " cannot redefine linker defined symbol '"
+ << gotSymName << "'";
return;
}
@@ -1413,8 +1413,8 @@ template <class ELFT> void Writer<ELFT>::resolveShfLinkOrder() {
if (isec->flags & SHF_LINK_ORDER) {
InputSection *link = isec->getLinkOrderDep();
if (link && !link->getParent())
- error(toString(isec) + ": sh_link points to discarded section " +
- toString(link));
+ ErrAlways(ctx) << isec << ": sh_link points to discarded section "
+ << link;
hasLinkOrder = true;
}
scriptSections.push_back(&isec);
@@ -1475,8 +1475,8 @@ template <class ELFT> void Writer<ELFT>::finalizeAddressDependentContent() {
// With Thunk Size much smaller than branch range we expect to
// converge quickly; if we get to 30 something has gone wrong.
if (changed && pass >= 30) {
- error(ctx.target->needsThunks ? "thunk creation not converged"
- : "relaxation not converged");
+ Err(ctx) << (ctx.target->needsThunks ? "thunk creation not converged"
+ : "relaxation not converged");
break;
}
@@ -2104,9 +2104,9 @@ template <class ELFT> void Writer<ELFT>::checkExecuteOnly() {
if (osec->flags & SHF_EXECINSTR)
for (InputSection *isec : getInputSections(*osec, storage))
if (!(isec->flags & SHF_EXECINSTR))
- error("cannot place " + toString(isec) + " into " +
- toString(osec->name) +
- ": --execute-only does not support intermingling data and code");
+ ErrAlways(ctx) << "cannot place " << isec << " into " << osec->name
+ << ": --execute-only does not support intermingling "
+ "data and code";
}
// The linker is expected to define SECNAME_start and SECNAME_end
@@ -2236,8 +2236,8 @@ SmallVector<PhdrEntry *, 0> Writer<ELFT>::createPhdrs(Partition &part) {
if (!relroEnd)
relRo->add(sec);
else
- error("section: " + sec->name + " is not contiguous with other relro" +
- " sections");
+ ErrAlways(ctx) << "section: " << sec->name
+ << " is not contiguous with other relro" << " sections";
} else if (inRelroPhdr) {
inRelroPhdr = false;
relroEnd = sec;
@@ -2562,9 +2562,10 @@ template <class ELFT> void Writer<ELFT>::assignFileOffsets() {
if (sec->type == SHT_NOBITS)
continue;
if ((sec->offset > fileSize) || (sec->offset + sec->size > fileSize))
- error("unable to place section " + sec->name + " at file offset " +
- rangeToString(sec->offset, sec->size) +
- "; check your linker script for overflows");
+ ErrAlways(ctx) << "unable to place section " << sec->name
+ << " at file offset "
+ << rangeToString(sec->offset, sec->size)
+ << "; check your linker script for overflows";
}
}
@@ -2785,7 +2786,7 @@ template <class ELFT> void Writer<ELFT>::openFile() {
<< "section sizes:\n";
for (OutputSection *os : ctx.outputSections)
s << os->name << ' ' << os->size << "\n";
- error(msg);
+ ErrAlways(ctx) << msg;
return;
}
@@ -2799,8 +2800,8 @@ template <class ELFT> void Writer<ELFT>::openFile() {
FileOutputBuffer::create(ctx.arg.outputFile, fileSize, flags);
if (!bufferOrErr) {
- error("failed to open " + ctx.arg.outputFile + ": " +
- llvm::toString(bufferOrErr.takeError()));
+ ErrAlways(ctx) << "failed to open " << ctx.arg.outputFile << ": "
+ << llvm::toString(bufferOrErr.takeError());
return;
}
buffer = std::move(*bufferOrErr);
@@ -2940,7 +2941,7 @@ template <class ELFT> void Writer<ELFT>::writeBuildId() {
break;
case BuildIdKind::Uuid:
if (auto ec = llvm::getRandomBytes(buildId.get(), hashSize))
- error("entropy source failure: " + ec.message());
+ ErrAlways(ctx) << "entropy source failure: " << ec.message();
break;
default:
llvm_unreachable("unknown BuildIdKind");
More information about the llvm-commits
mailing list