summaryrefslogtreecommitdiffstats
path: root/lld/ELF
diff options
context:
space:
mode:
authorRui Ueyama <ruiu@google.com>2016-01-28 18:40:06 +0000
committerRui Ueyama <ruiu@google.com>2016-01-28 18:40:06 +0000
commit64cfffd333b261ebb68a6ee04b09cc42d32c1992 (patch)
tree3320a40b26ea9552b91802bbf4b83767398f1f1e /lld/ELF
parentec8d086c64f4012714405fb0d7b0729a33c18179 (diff)
downloadbcm5719-llvm-64cfffd333b261ebb68a6ee04b09cc42d32c1992.tar.gz
bcm5719-llvm-64cfffd333b261ebb68a6ee04b09cc42d32c1992.zip
ELF: Rename error -> fatal and redefine error as a non-noreturn function.
In many situations, we don't want to exit at the first error even in the process model. For example, it is better to report all undefined symbols rather than reporting the first one that the linker picked up randomly. In order to handle such errors, we don't need to wrap everything with ErrorOr (thanks for David Blaikie for pointing this out!) Instead, we can set a flag to record the fact that we found an error and keep it going until it reaches a reasonable checkpoint. This idea should be applicable to other places. For example, we can ignore broken relocations and check for errors after visiting all relocs. In this patch, I rename error to fatal, and introduce another version of error which doesn't call exit. That function instead sets HasError to true. Once HasError becomes true, it stays true, so that we know that there was an error if it is true. I think introducing a non-noreturn error reporting function is by itself a good idea, and it looks to me that this also provides a gradual path towards lld-as-a-library (or at least embed-lld-to-your-program) without sacrificing code readability with lots of ErrorOr's. http://reviews.llvm.org/D16641 llvm-svn: 259069
Diffstat (limited to 'lld/ELF')
-rw-r--r--lld/ELF/Driver.cpp30
-rw-r--r--lld/ELF/Driver.h4
-rw-r--r--lld/ELF/DriverUtils.cpp6
-rw-r--r--lld/ELF/Error.cpp29
-rw-r--r--lld/ELF/Error.h13
-rw-r--r--lld/ELF/InputFiles.cpp60
-rw-r--r--lld/ELF/InputSection.cpp8
-rw-r--r--lld/ELF/LinkerScript.cpp18
-rw-r--r--lld/ELF/OutputSections.cpp42
-rw-r--r--lld/ELF/SymbolTable.cpp6
-rw-r--r--lld/ELF/Target.cpp28
-rw-r--r--lld/ELF/Writer.cpp8
12 files changed, 140 insertions, 112 deletions
diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp
index f48b594e31f..a0fc13af472 100644
--- a/lld/ELF/Driver.cpp
+++ b/lld/ELF/Driver.cpp
@@ -29,12 +29,14 @@ using namespace lld::elf2;
Configuration *elf2::Config;
LinkerDriver *elf2::Driver;
-void elf2::link(ArrayRef<const char *> Args) {
+bool elf2::link(ArrayRef<const char *> Args) {
+ HasError = false;
Configuration C;
LinkerDriver D;
Config = &C;
Driver = &D;
Driver->main(Args.slice(1));
+ return !HasError;
}
static std::pair<ELFKind, uint16_t> parseEmulation(StringRef S) {
@@ -53,22 +55,22 @@ static std::pair<ELFKind, uint16_t> parseEmulation(StringRef S) {
if (S == "aarch64linux")
return {ELF64LEKind, EM_AARCH64};
if (S == "i386pe" || S == "i386pep" || S == "thumb2pe")
- error("Windows targets are not supported on the ELF frontend: " + S);
- error("Unknown emulation: " + S);
+ fatal("Windows targets are not supported on the ELF frontend: " + S);
+ fatal("Unknown emulation: " + S);
}
// Returns slices of MB by parsing MB as an archive file.
// Each slice consists of a member file in the archive.
static std::vector<MemoryBufferRef> getArchiveMembers(MemoryBufferRef MB) {
ErrorOr<std::unique_ptr<Archive>> FileOrErr = Archive::create(MB);
- error(FileOrErr, "Failed to parse archive");
+ fatal(FileOrErr, "Failed to parse archive");
std::unique_ptr<Archive> File = std::move(*FileOrErr);
std::vector<MemoryBufferRef> V;
for (const ErrorOr<Archive::Child> &C : File->children()) {
- error(C, "Could not get the child of the archive " + File->getFileName());
+ fatal(C, "Could not get the child of the archive " + File->getFileName());
ErrorOr<MemoryBufferRef> MbOrErr = C->getMemoryBufferRef();
- error(MbOrErr, "Could not get the buffer for a child of the archive " +
+ fatal(MbOrErr, "Could not get the buffer for a child of the archive " +
File->getFileName());
V.push_back(*MbOrErr);
}
@@ -82,7 +84,7 @@ void LinkerDriver::addFile(StringRef Path) {
if (Config->Verbose)
llvm::outs() << Path << "\n";
auto MBOrErr = MemoryBuffer::getFile(Path);
- error(MBOrErr, "cannot open " + Path);
+ fatal(MBOrErr, "cannot open " + Path);
std::unique_ptr<MemoryBuffer> &MB = *MBOrErr;
MemoryBufferRef MBRef = MB->getMemBufferRef();
OwningMBs.push_back(std::move(MB)); // take MB ownership
@@ -114,15 +116,15 @@ static void checkOptions(opt::InputArgList &Args) {
// of executables or DSOs. We don't support that since the feature
// does not seem to provide more value than the static archiver.
if (Args.hasArg(OPT_relocatable))
- error("-r option is not supported. Use 'ar' command instead.");
+ fatal("-r option is not supported. Use 'ar' command instead.");
// The MIPS ABI as of 2016 does not support the GNU-style symbol lookup
// table which is a relatively new feature.
if (Config->EMachine == EM_MIPS && Config->GnuHash)
- error("The .gnu.hash section is not compatible with the MIPS target.");
+ fatal("The .gnu.hash section is not compatible with the MIPS target.");
if (Config->EMachine == EM_AMDGPU && !Config->Entry.empty())
- error("-e option is not valid for AMDGPU.");
+ fatal("-e option is not valid for AMDGPU.");
}
static StringRef
@@ -161,7 +163,7 @@ void LinkerDriver::main(ArrayRef<const char *> ArgsArr) {
link<ELF64BE>(Args);
return;
default:
- error("-m or at least a .o file required");
+ fatal("-m or at least a .o file required");
}
}
@@ -217,7 +219,7 @@ void LinkerDriver::readConfigs(opt::InputArgList &Args) {
if (auto *Arg = Args.getLastArg(OPT_O)) {
StringRef Val = Arg->getValue();
if (Val.getAsInteger(10, Config->Optimize))
- error("Invalid optimization level");
+ fatal("Invalid optimization level");
}
if (auto *Arg = Args.getLastArg(OPT_hash_style)) {
@@ -228,7 +230,7 @@ void LinkerDriver::readConfigs(opt::InputArgList &Args) {
} else if (S == "both") {
Config->GnuHash = true;
} else if (S != "sysv")
- error("Unknown hash style: " + S);
+ fatal("Unknown hash style: " + S);
}
for (auto *Arg : Args.filtered(OPT_undefined))
@@ -267,7 +269,7 @@ void LinkerDriver::createFiles(opt::InputArgList &Args) {
}
if (Files.empty())
- error("no input files.");
+ fatal("no input files.");
}
template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) {
diff --git a/lld/ELF/Driver.h b/lld/ELF/Driver.h
index 720ef46dc71..95b6d968c86 100644
--- a/lld/ELF/Driver.h
+++ b/lld/ELF/Driver.h
@@ -20,8 +20,8 @@ namespace elf2 {
extern class LinkerDriver *Driver;
-// Entry point of the ELF linker.
-void link(ArrayRef<const char *> Args);
+// Entry point of the ELF linker. Returns true on success.
+bool link(ArrayRef<const char *> Args);
class LinkerDriver {
public:
diff --git a/lld/ELF/DriverUtils.cpp b/lld/ELF/DriverUtils.cpp
index 965ed4f00a6..52e463350f0 100644
--- a/lld/ELF/DriverUtils.cpp
+++ b/lld/ELF/DriverUtils.cpp
@@ -66,7 +66,7 @@ opt::InputArgList elf2::parseArgs(llvm::BumpPtrAllocator *A,
// Parse options and then do error checking.
opt::InputArgList Args = Table.ParseArgs(Vec, MissingIndex, MissingCount);
if (MissingCount)
- error(Twine("missing arg value for \"") + Args.getArgString(MissingIndex) +
+ fatal(Twine("missing arg value for \"") + Args.getArgString(MissingIndex) +
"\", expected " + Twine(MissingCount) +
(MissingCount == 1 ? " argument.\n" : " arguments"));
@@ -74,7 +74,7 @@ opt::InputArgList elf2::parseArgs(llvm::BumpPtrAllocator *A,
for (auto *Arg : Unknowns)
warning("warning: unknown argument: " + Arg->getSpelling());
if (Unknowns.begin() != Unknowns.end())
- error("unknown argument(s) found");
+ fatal("unknown argument(s) found");
return Args;
}
@@ -104,7 +104,7 @@ std::string elf2::searchLibrary(StringRef Path) {
if (!S.empty())
return S;
}
- error("Unable to find library -l" + Path);
+ fatal("Unable to find library -l" + Path);
}
// Makes a path by concatenating Dir and File.
diff --git a/lld/ELF/Error.cpp b/lld/ELF/Error.cpp
index e0701f7f4cc..327bb26a4f1 100644
--- a/lld/ELF/Error.cpp
+++ b/lld/ELF/Error.cpp
@@ -15,23 +15,38 @@
namespace lld {
namespace elf2 {
+bool HasError;
+
void warning(const Twine &Msg) { llvm::errs() << Msg << "\n"; }
void error(const Twine &Msg) {
llvm::errs() << Msg << "\n";
- exit(1);
+ HasError = true;
}
void error(std::error_code EC, const Twine &Prefix) {
- if (!EC)
- return;
- error(Prefix + ": " + EC.message());
+ if (EC)
+ error(Prefix + ": " + EC.message());
}
void error(std::error_code EC) {
- if (!EC)
- return;
- error(EC.message());
+ if (EC)
+ error(EC.message());
+}
+
+void fatal(const Twine &Msg) {
+ llvm::errs() << Msg << "\n";
+ exit(1);
+}
+
+void fatal(std::error_code EC, const Twine &Prefix) {
+ if (EC)
+ fatal(Prefix + ": " + EC.message());
+}
+
+void fatal(std::error_code EC) {
+ if (EC)
+ fatal(EC.message());
}
} // namespace elf2
diff --git a/lld/ELF/Error.h b/lld/ELF/Error.h
index b1d2e7a8fc5..3b6aa693ec8 100644
--- a/lld/ELF/Error.h
+++ b/lld/ELF/Error.h
@@ -15,9 +15,11 @@
namespace lld {
namespace elf2 {
+extern bool HasError;
+
void warning(const Twine &Msg);
-LLVM_ATTRIBUTE_NORETURN void error(const Twine &Msg);
+void error(const Twine &Msg);
void error(std::error_code EC, const Twine &Prefix);
void error(std::error_code EC);
@@ -26,6 +28,15 @@ template <typename T> void error(const ErrorOr<T> &V, const Twine &Prefix) {
}
template <typename T> void error(const ErrorOr<T> &V) { error(V.getError()); }
+LLVM_ATTRIBUTE_NORETURN void fatal(const Twine &Msg);
+void fatal(std::error_code EC, const Twine &Prefix);
+void fatal(std::error_code EC);
+
+template <typename T> void fatal(const ErrorOr<T> &V, const Twine &Prefix) {
+ fatal(V.getError(), Prefix);
+}
+template <typename T> void fatal(const ErrorOr<T> &V) { fatal(V.getError()); }
+
} // namespace elf2
} // namespace lld
diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp
index b43a9b39309..fa7c339da19 100644
--- a/lld/ELF/InputFiles.cpp
+++ b/lld/ELF/InputFiles.cpp
@@ -27,7 +27,7 @@ class ECRAII {
public:
std::error_code &getEC() { return EC; }
- ~ECRAII() { error(EC); }
+ ~ECRAII() { fatal(EC); }
};
}
@@ -51,7 +51,7 @@ ELFFileBase<ELFT>::getSymbolsHelper(bool Local) {
uint32_t NumSymbols = std::distance(Syms.begin(), Syms.end());
uint32_t FirstNonLocal = Symtab->sh_info;
if (FirstNonLocal > NumSymbols)
- error("Invalid sh_info in symbol table");
+ fatal("Invalid sh_info in symbol table");
if (!Local)
return make_range(Syms.begin() + FirstNonLocal, Syms.end());
// +1 to skip over dummy symbol.
@@ -72,7 +72,7 @@ template <class ELFT> void ELFFileBase<ELFT>::initStringTable() {
if (!Symtab)
return;
ErrorOr<StringRef> StringTableOrErr = ELFObj.getStringTableForSymtab(*Symtab);
- error(StringTableOrErr);
+ fatal(StringTableOrErr);
StringTable = *StringTableOrErr;
}
@@ -122,14 +122,14 @@ StringRef ObjectFile<ELFT>::getShtGroupSignature(const Elf_Shdr &Sec) {
const ELFFile<ELFT> &Obj = this->ELFObj;
uint32_t SymtabdSectionIndex = Sec.sh_link;
ErrorOr<const Elf_Shdr *> SecOrErr = Obj.getSection(SymtabdSectionIndex);
- error(SecOrErr);
+ fatal(SecOrErr);
const Elf_Shdr *SymtabSec = *SecOrErr;
uint32_t SymIndex = Sec.sh_info;
const Elf_Sym *Sym = Obj.getSymbol(SymtabSec, SymIndex);
ErrorOr<StringRef> StringTableOrErr = Obj.getStringTableForSymtab(*SymtabSec);
- error(StringTableOrErr);
+ fatal(StringTableOrErr);
ErrorOr<StringRef> SignatureOrErr = Sym->getName(*StringTableOrErr);
- error(SignatureOrErr);
+ fatal(SignatureOrErr);
return *SignatureOrErr;
}
@@ -139,10 +139,10 @@ ObjectFile<ELFT>::getShtGroupEntries(const Elf_Shdr &Sec) {
const ELFFile<ELFT> &Obj = this->ELFObj;
ErrorOr<ArrayRef<uint32_X>> EntriesOrErr =
Obj.template getSectionContentsAsArray<uint32_X>(&Sec);
- error(EntriesOrErr);
+ fatal(EntriesOrErr);
ArrayRef<uint32_X> Entries = *EntriesOrErr;
if (Entries.empty() || Entries[0] != GRP_COMDAT)
- error("Unsupported SHT_GROUP format");
+ fatal("Unsupported SHT_GROUP format");
return Entries.slice(1);
}
@@ -153,10 +153,10 @@ static bool shouldMerge(const typename ELFFile<ELFT>::Elf_Shdr &Sec) {
if (!(Flags & SHF_MERGE))
return false;
if (Flags & SHF_WRITE)
- error("Writable SHF_MERGE sections are not supported");
+ fatal("Writable SHF_MERGE sections are not supported");
uintX_t EntSize = Sec.sh_entsize;
if (!EntSize || Sec.sh_size % EntSize)
- error("SHF_MERGE section size must be a multiple of sh_entsize");
+ fatal("SHF_MERGE section size must be a multiple of sh_entsize");
// Don't try to merge if the aligment is larger than the sh_entsize.
//
@@ -191,7 +191,7 @@ void ObjectFile<ELFT>::initializeSections(DenseSet<StringRef> &ComdatGroups) {
continue;
for (uint32_t SecIndex : getShtGroupEntries(Sec)) {
if (SecIndex >= Size)
- error("Invalid section index in group");
+ fatal("Invalid section index in group");
Sections[SecIndex] = &InputSection<ELFT>::Discarded;
}
break;
@@ -200,7 +200,7 @@ void ObjectFile<ELFT>::initializeSections(DenseSet<StringRef> &ComdatGroups) {
break;
case SHT_SYMTAB_SHNDX: {
ErrorOr<ArrayRef<Elf_Word>> ErrorOrTable = Obj.getSHNDXTable(Sec);
- error(ErrorOrTable);
+ fatal(ErrorOrTable);
this->SymtabSHNDX = *ErrorOrTable;
break;
}
@@ -211,19 +211,19 @@ void ObjectFile<ELFT>::initializeSections(DenseSet<StringRef> &ComdatGroups) {
case SHT_REL: {
uint32_t RelocatedSectionIndex = Sec.sh_info;
if (RelocatedSectionIndex >= Size)
- error("Invalid relocated section index");
+ fatal("Invalid relocated section index");
InputSectionBase<ELFT> *RelocatedSection =
Sections[RelocatedSectionIndex];
if (!RelocatedSection)
- error("Unsupported relocation reference");
+ fatal("Unsupported relocation reference");
if (auto *S = dyn_cast<InputSection<ELFT>>(RelocatedSection)) {
S->RelocSections.push_back(&Sec);
} else if (auto *S = dyn_cast<EHInputSection<ELFT>>(RelocatedSection)) {
if (S->RelocSection)
- error("Multiple relocation sections to .eh_frame are not supported");
+ fatal("Multiple relocation sections to .eh_frame are not supported");
S->RelocSection = &Sec;
} else {
- error("Relocations pointing to SHF_MERGE are not supported");
+ fatal("Relocations pointing to SHF_MERGE are not supported");
}
break;
}
@@ -236,7 +236,7 @@ void ObjectFile<ELFT>::initializeSections(DenseSet<StringRef> &ComdatGroups) {
template <class ELFT> InputSectionBase<ELFT> *
ObjectFile<ELFT>::createInputSection(const Elf_Shdr &Sec) {
ErrorOr<StringRef> NameOrErr = this->ELFObj.getSectionName(&Sec);
- error(NameOrErr);
+ fatal(NameOrErr);
StringRef Name = *NameOrErr;
// .note.GNU-stack is a marker section to control the presence of
@@ -276,14 +276,14 @@ ObjectFile<ELFT>::getSection(const Elf_Sym &Sym) const {
if (Index == 0)
return nullptr;
if (Index >= Sections.size() || !Sections[Index])
- error("Invalid section index");
+ fatal("Invalid section index");
return Sections[Index];
}
template <class ELFT>
SymbolBody *ObjectFile<ELFT>::createSymbolBody(const Elf_Sym *Sym) {
ErrorOr<StringRef> NameOrErr = Sym->getName(this->StringTable);
- error(NameOrErr);
+ fatal(NameOrErr);
StringRef Name = *NameOrErr;
switch (Sym->st_shndx) {
@@ -297,7 +297,7 @@ SymbolBody *ObjectFile<ELFT>::createSymbolBody(const Elf_Sym *Sym) {
switch (Sym->getBinding()) {
default:
- error("unexpected binding");
+ fatal("unexpected binding");
case STB_GLOBAL:
case STB_WEAK:
case STB_GNU_UNIQUE: {
@@ -311,7 +311,7 @@ SymbolBody *ObjectFile<ELFT>::createSymbolBody(const Elf_Sym *Sym) {
void ArchiveFile::parse() {
ErrorOr<std::unique_ptr<Archive>> FileOrErr = Archive::create(MB);
- error(FileOrErr, "Failed to parse archive");
+ fatal(FileOrErr, "Failed to parse archive");
File = std::move(*FileOrErr);
// Allocate a buffer for Lazy objects.
@@ -326,7 +326,7 @@ void ArchiveFile::parse() {
// Returns a buffer pointing to a member file containing a given symbol.
MemoryBufferRef ArchiveFile::getMember(const Archive::Symbol *Sym) {
ErrorOr<Archive::Child> COrErr = Sym->getMember();
- error(COrErr, "Could not get the member for symbol " + Sym->getName());
+ fatal(COrErr, "Could not get the member for symbol " + Sym->getName());
const Archive::Child &C = *COrErr;
if (!Seen.insert(C.getChildOffset()).second)
@@ -334,8 +334,8 @@ MemoryBufferRef ArchiveFile::getMember(const Archive::Symbol *Sym) {
ErrorOr<MemoryBufferRef> RefOrErr = C.getMemoryBufferRef();
if (!RefOrErr)
- error(RefOrErr, "Could not get the buffer for the member defining symbol " +
- Sym->getName());
+ fatal(RefOrErr, "Could not get the buffer for the member defining symbol " +
+ Sym->getName());
return *RefOrErr;
}
@@ -350,7 +350,7 @@ SharedFile<ELFT>::getSection(const Elf_Sym &Sym) const {
if (Index == 0)
return nullptr;
ErrorOr<const Elf_Shdr *> Ret = this->ELFObj.getSection(Index);
- error(Ret);
+ fatal(Ret);
return *Ret;
}
@@ -374,7 +374,7 @@ template <class ELFT> void SharedFile<ELFT>::parseSoName() {
break;
case SHT_SYMTAB_SHNDX: {
ErrorOr<ArrayRef<Elf_Word>> ErrorOrTable = Obj.getSHNDXTable(Sec);
- error(ErrorOrTable);
+ fatal(ErrorOrTable);
this->SymtabSHNDX = *ErrorOrTable;
break;
}
@@ -394,7 +394,7 @@ template <class ELFT> void SharedFile<ELFT>::parseSoName() {
if (Dyn.d_tag == DT_SONAME) {
uintX_t Val = Dyn.getVal();
if (Val >= this->StringTable.size())
- error("Invalid DT_SONAME entry");
+ fatal("Invalid DT_SONAME entry");
SoName = StringRef(this->StringTable.data() + Val);
return;
}
@@ -408,7 +408,7 @@ template <class ELFT> void SharedFile<ELFT>::parseRest() {
SymbolBodies.reserve(NumSymbols);
for (const Elf_Sym &Sym : Syms) {
ErrorOr<StringRef> NameOrErr = Sym.getName(this->StringTable);
- error(NameOrErr.getError());
+ fatal(NameOrErr.getError());
StringRef Name = *NameOrErr;
if (Sym.isUndefined())
@@ -437,7 +437,7 @@ template <template <class> class T>
static std::unique_ptr<InputFile> createELFFile(MemoryBufferRef MB) {
std::pair<unsigned char, unsigned char> Type = getElfArchType(MB.getBuffer());
if (Type.second != ELF::ELFDATA2LSB && Type.second != ELF::ELFDATA2MSB)
- error("Invalid data encoding: " + MB.getBufferIdentifier());
+ fatal("Invalid data encoding: " + MB.getBufferIdentifier());
if (Type.first == ELF::ELFCLASS32) {
if (Type.second == ELF::ELFDATA2LSB)
@@ -449,7 +449,7 @@ static std::unique_ptr<InputFile> createELFFile(MemoryBufferRef MB) {
return createELFFileAux<T<ELF64LE>>(MB);
return createELFFileAux<T<ELF64BE>>(MB);
}
- error("Invalid file class: " + MB.getBufferIdentifier());
+ fatal("Invalid file class: " + MB.getBufferIdentifier());
}
std::unique_ptr<InputFile> elf2::createObjectFile(MemoryBufferRef MB) {
diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp
index 20cc2479ebb..3d242207859 100644
--- a/lld/ELF/InputSection.cpp
+++ b/lld/ELF/InputSection.cpp
@@ -29,7 +29,7 @@ InputSectionBase<ELFT>::InputSectionBase(ObjectFile<ELFT> *File,
template <class ELFT> StringRef InputSectionBase<ELFT>::getSectionName() const {
ErrorOr<StringRef> Name = File->getObj().getSectionName(this->Header);
- error(Name);
+ fatal(Name);
return *Name;
}
@@ -37,7 +37,7 @@ template <class ELFT>
ArrayRef<uint8_t> InputSectionBase<ELFT>::getSectionData() const {
ErrorOr<ArrayRef<uint8_t>> Ret =
this->File->getObj().getSectionContents(this->Header);
- error(Ret);
+ fatal(Ret);
return *Ret;
}
@@ -325,7 +325,7 @@ SplitInputSection<ELFT>::getRangeAndSize(uintX_t Offset) {
StringRef Data((const char *)D.data(), D.size());
uintX_t Size = Data.size();
if (Offset >= Size)
- error("Entry is past the end of the section");
+ fatal("Entry is past the end of the section");
// Find the element this offset points to.
auto I = std::upper_bound(
@@ -369,7 +369,7 @@ MipsReginfoInputSection<ELFT>::MipsReginfoInputSection(ObjectFile<ELFT> *F,
// Initialize this->Reginfo.
ArrayRef<uint8_t> D = this->getSectionData();
if (D.size() != sizeof(Elf_Mips_RegInfo<ELFT>))
- error("Invalid size of .reginfo section");
+ fatal("Invalid size of .reginfo section");
Reginfo = reinterpret_cast<const Elf_Mips_RegInfo<ELFT> *>(D.data());
}
diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp
index 1345bd4f973..d9f98e9bbff 100644
--- a/lld/ELF/LinkerScript.cpp
+++ b/lld/ELF/LinkerScript.cpp
@@ -86,7 +86,7 @@ void LinkerScript::run() {
} else if (Tok == "SECTIONS") {
readSections();
} else {
- error("unknown directive: " + Tok);
+ fatal("unknown directive: " + Tok);
}
}
}
@@ -103,7 +103,7 @@ std::vector<StringRef> LinkerScript::tokenize(StringRef S) {
if (S.startswith("\"")) {
size_t E = S.find("\"", 1);
if (E == StringRef::npos)
- error("unclosed quote");
+ fatal("unclosed quote");
Ret.push_back(S.substr(1, E - 1));
S = S.substr(E + 1);
continue;
@@ -128,7 +128,7 @@ StringRef LinkerScript::skipSpace(StringRef S) {
if (S.startswith("/*")) {
size_t E = S.find("*/", 2);
if (E == StringRef::npos)
- error("unclosed comment in a linker script");
+ fatal("unclosed comment in a linker script");
S = S.substr(E + 2);
continue;
}
@@ -141,13 +141,13 @@ StringRef LinkerScript::skipSpace(StringRef S) {
StringRef LinkerScript::next() {
if (atEOF())
- error("unexpected EOF");
+ fatal("unexpected EOF");
return Tokens[Pos++];
}
bool LinkerScript::skip(StringRef Tok) {
if (atEOF())
- error("unexpected EOF");
+ fatal("unexpected EOF");
if (Tok != Tokens[Pos])
return false;
++Pos;
@@ -157,7 +157,7 @@ bool LinkerScript::skip(StringRef Tok) {
void LinkerScript::expect(StringRef Expect) {
StringRef Tok = next();
if (Tok != Expect)
- error(Expect + " expected, but got " + Tok);
+ fatal(Expect + " expected, but got " + Tok);
}
void LinkerScript::addFile(StringRef S) {
@@ -184,7 +184,7 @@ void LinkerScript::addFile(StringRef S) {
} else {
std::string Path = findFromSearchPaths(S);
if (Path.empty())
- error("Unable to find " + S);
+ fatal("Unable to find " + S);
Driver->addFile(Saver.save(Path));
}
}
@@ -238,7 +238,7 @@ void LinkerScript::readGroup() {
void LinkerScript::readInclude() {
StringRef Tok = next();
auto MBOrErr = MemoryBuffer::getFile(Tok);
- error(MBOrErr, "cannot open " + Tok);
+ fatal(MBOrErr, "cannot open " + Tok);
std::unique_ptr<MemoryBuffer> &MB = *MBOrErr;
StringRef S = Saver.save(MB->getMemBufferRef().getBuffer());
std::vector<StringRef> V = tokenize(S);
@@ -269,7 +269,7 @@ void LinkerScript::readOutputFormat() {
if (Tok == ")")
return;
if (Tok != ",")
- error("unexpected token: " + Tok);
+ fatal("unexpected token: " + Tok);
next();
expect(",");
next();
diff --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp
index 4bdbeb97694..76fb2ea4fa6 100644
--- a/lld/ELF/OutputSections.cpp
+++ b/lld/ELF/OutputSections.cpp
@@ -770,7 +770,7 @@ EhFrameHeader<ELFT>::getFdePc(uintX_t EhVA, const FdeData &F) {
return FdeOff + read64<E>(F.PCRel);
return FdeOff + read32<E>(F.PCRel);
}
- error("unknown FDE size encoding");
+ fatal("unknown FDE size encoding");
}
template <class ELFT> void EhFrameHeader<ELFT>::writeTo(uint8_t *Buf) {
@@ -813,7 +813,7 @@ void EhFrameHeader<ELFT>::assignEhFrame(EHOutputSection<ELFT> *Sec) {
template <class ELFT>
void EhFrameHeader<ELFT>::addFde(uint8_t Enc, size_t Off, uint8_t *PCRel) {
if (Live && (Enc & 0xF0) == dwarf::DW_EH_PE_datarel)
- error("DW_EH_PE_datarel encoding unsupported for FDEs by .eh_frame_hdr");
+ fatal("DW_EH_PE_datarel encoding unsupported for FDEs by .eh_frame_hdr");
FdeList.push_back(FdeData{Enc, Off, PCRel});
}
@@ -904,7 +904,7 @@ elf2::getLocalRelTarget(const ObjectFile<ELFT> &File,
File.getObj().getRelocationSymbol(&RI, File.getSymbolTable());
if (!Sym)
- error("Unsupported relocation without symbol");
+ fatal("Unsupported relocation without symbol");
InputSectionBase<ELFT> *Section = File.getSection(*Sym);
@@ -1001,7 +1001,7 @@ Cie<ELFT>::Cie(EHInputSection<ELFT> *S, unsigned Index)
// Read a byte and advance D by one byte.
static uint8_t readByte(ArrayRef<uint8_t> &D) {
if (D.empty())
- error("corrupted or unsupported CIE information");
+ fatal("corrupted or unsupported CIE information");
uint8_t B = D.front();
D = D.slice(1);
return B;
@@ -1014,14 +1014,14 @@ static void skipLeb128(ArrayRef<uint8_t> &D) {
if ((Val & 0x80) == 0)
return;
}
- error("corrupted or unsupported CIE information");
+ fatal("corrupted or unsupported CIE information");
}
template <class ELFT> static unsigned getSizeForEncoding(unsigned Enc) {
typedef typename ELFFile<ELFT>::uintX_t uintX_t;
switch (Enc & 0x0f) {
default:
- error("unknown FDE encoding");
+ fatal("unknown FDE encoding");
case dwarf::DW_EH_PE_absptr:
case dwarf::DW_EH_PE_signed:
return sizeof(uintX_t);
@@ -1041,7 +1041,7 @@ template <class ELFT>
uint8_t EHOutputSection<ELFT>::getFdeEncoding(ArrayRef<uint8_t> D) {
auto Check = [](bool C) {
if (!C)
- error("corrupted or unsupported CIE information");
+ fatal("corrupted or unsupported CIE information");
};
Check(D.size() >= 8);
@@ -1049,7 +1049,7 @@ uint8_t EHOutputSection<ELFT>::getFdeEncoding(ArrayRef<uint8_t> D) {
uint8_t Version = readByte(D);
if (Version != 1 && Version != 3)
- error("FDE version 1 or 3 expected, but got " + Twine((unsigned)Version));
+ fatal("FDE version 1 or 3 expected, but got " + Twine((unsigned)Version));
auto AugEnd = std::find(D.begin() + 1, D.end(), '\0');
Check(AugEnd != D.end());
@@ -1058,7 +1058,7 @@ uint8_t EHOutputSection<ELFT>::getFdeEncoding(ArrayRef<uint8_t> D) {
// Code alignment factor should always be 1 for .eh_frame.
if (readByte(D) != 1)
- error("CIE code alignment must be 1");
+ fatal("CIE code alignment must be 1");
// Skip data alignment factor
skipLeb128(D);
@@ -1079,7 +1079,7 @@ uint8_t EHOutputSection<ELFT>::getFdeEncoding(ArrayRef<uint8_t> D) {
case 'P': {
uint8_t Enc = readByte(D);
if ((Enc & 0xf0) == dwarf::DW_EH_PE_aligned)
- error("DW_EH_PE_aligned encoding for address of a personality routine "
+ fatal("DW_EH_PE_aligned encoding for address of a personality routine "
"handler not supported");
unsigned EncSize = getSizeForEncoding<ELFT>(Enc);
Check(D.size() >= EncSize);
@@ -1093,7 +1093,7 @@ uint8_t EHOutputSection<ELFT>::getFdeEncoding(ArrayRef<uint8_t> D) {
// handler
break;
default:
- error("unknown .eh_frame augmentation string value");
+ fatal("unknown .eh_frame augmentation string value");
}
}
return dwarf::DW_EH_PE_absptr;
@@ -1159,13 +1159,13 @@ void EHOutputSection<ELFT>::addSectionAux(
OffsetToIndex[Offset] = P.first->second;
} else {
if (!HasReloc)
- error("FDE doesn't reference another section");
+ fatal("FDE doesn't reference another section");
InputSectionBase<ELFT> *Target = S->getRelocTarget(*RelI);
if (Target != &InputSection<ELFT>::Discarded && Target->isLive()) {
uint32_t CieOffset = Offset + 4 - ID;
auto I = OffsetToIndex.find(CieOffset);
if (I == OffsetToIndex.end())
- error("Invalid CIE reference");
+ fatal("Invalid CIE reference");
Cies[I->second].Fdes.push_back(EHRegion<ELFT>(S, Index));
Out<ELFT>::EhFrameHdr->reserveFde();
this->Header.sh_size += alignTo(Length, sizeof(uintX_t));
@@ -1183,23 +1183,23 @@ EHOutputSection<ELFT>::readEntryLength(ArrayRef<uint8_t> D) {
const endianness E = ELFT::TargetEndianness;
if (D.size() < 4)
- error("Truncated CIE/FDE length");
+ fatal("Truncated CIE/FDE length");
uint64_t Len = read32<E>(D.data());
if (Len < UINT32_MAX) {
if (Len > (UINT32_MAX - 4))
- error("CIE/FIE size is too large");
+ fatal("CIE/FIE size is too large");
if (Len + 4 > D.size())
- error("CIE/FIE ends past the end of the section");
+ fatal("CIE/FIE ends past the end of the section");
return Len + 4;
}
if (D.size() < 12)
- error("Truncated CIE/FDE length");
+ fatal("Truncated CIE/FDE length");
Len = read64<E>(D.data() + 4);
if (Len > (UINT64_MAX - 12))
- error("CIE/FIE size is too large");
+ fatal("CIE/FIE size is too large");
if (Len + 12 > D.size())
- error("CIE/FIE ends past the end of the section");
+ fatal("CIE/FIE ends past the end of the section");
return Len + 12;
}
@@ -1307,7 +1307,7 @@ void MergeOutputSection<ELFT>::addSection(InputSectionBase<ELFT> *C) {
while (!Data.empty()) {
size_t End = findNull(Data, EntSize);
if (End == StringRef::npos)
- error("String is not null terminated");
+ fatal("String is not null terminated");
StringRef Entry = Data.substr(0, End + EntSize);
uintX_t OutputOffset = Builder.add(Entry);
if (shouldTailMerge())
@@ -1462,7 +1462,7 @@ void SymbolTableSection<ELFT>::writeLocalSymbols(uint8_t *&Buf) {
for (const std::unique_ptr<ObjectFile<ELFT>> &File : Table.getObjectFiles()) {
for (const Elf_Sym *Sym : File->KeptLocalSyms) {
ErrorOr<StringRef> SymNameOrErr = Sym->getName(File->getStringTable());
- error(SymNameOrErr);
+ fatal(SymNameOrErr);
StringRef SymName = *SymNameOrErr;
auto *ESym = reinterpret_cast<Elf_Sym *>(Buf);
diff --git a/lld/ELF/SymbolTable.cpp b/lld/ELF/SymbolTable.cpp
index d3413102b60..1cb8b5d9a57 100644
--- a/lld/ELF/SymbolTable.cpp
+++ b/lld/ELF/SymbolTable.cpp
@@ -41,7 +41,7 @@ static void checkCompatibility(InputFile *FileP) {
StringRef B = Config->Emulation;
if (B.empty())
B = Config->FirstElf->getName();
- error(A + " is incompatible with " + B);
+ fatal(A + " is incompatible with " + B);
}
// Add symbols in File to the symbol table.
@@ -182,7 +182,7 @@ template <class ELFT> void SymbolTable<ELFT>::resolve(SymbolBody *New) {
}
if (New->isTls() != Existing->isTls())
- error("TLS attribute mismatch for symbol: " + conflictMsg(Existing, New));
+ fatal("TLS attribute mismatch for symbol: " + conflictMsg(Existing, New));
// compare() returns -1, 0, or 1 if the lhs symbol is less preferable,
// equivalent (conflicting), or more preferable, respectively.
@@ -190,7 +190,7 @@ template <class ELFT> void SymbolTable<ELFT>::resolve(SymbolBody *New) {
if (Comp == 0) {
std::string S = "duplicate symbol: " + conflictMsg(Existing, New);
if (!Config->AllowMultipleDefinition)
- error(S);
+ fatal(S);
warning(S);
return;
}
diff --git a/lld/ELF/Target.cpp b/lld/ELF/Target.cpp
index b9b054e81e9..808f2850e24 100644
--- a/lld/ELF/Target.cpp
+++ b/lld/ELF/Target.cpp
@@ -46,28 +46,28 @@ template <unsigned N> static void checkInt(int64_t V, uint32_t Type) {
if (isInt<N>(V))
return;
StringRef S = getELFRelocationTypeName(Config->EMachine, Type);
- error("Relocation " + S + " out of range");
+ fatal("Relocation " + S + " out of range");
}
template <unsigned N> static void checkUInt(uint64_t V, uint32_t Type) {
if (isUInt<N>(V))
return;
StringRef S = getELFRelocationTypeName(Config->EMachine, Type);
- error("Relocation " + S + " out of range");
+ fatal("Relocation " + S + " out of range");
}
template <unsigned N> static void checkIntUInt(uint64_t V, uint32_t Type) {
if (isInt<N>(V) || isUInt<N>(V))
return;
StringRef S = getELFRelocationTypeName(Config->EMachine, Type);
- error("Relocation " + S + " out of range");
+ fatal("Relocation " + S + " out of range");
}
template <unsigned N> static void checkAlignment(uint64_t V, uint32_t Type) {
if ((V & (N - 1)) == 0)
return;
StringRef S = getELFRelocationTypeName(Config->EMachine, Type);
- error("Improper alignment for relocation " + S);
+ fatal("Improper alignment for relocation " + S);
}
template <class ELFT> bool isGnuIFunc(const SymbolBody &S) {
@@ -260,7 +260,7 @@ TargetInfo *createTarget() {
case ELF32BEKind:
return new MipsTargetInfo<ELF32BE>();
default:
- error("Unsupported MIPS target");
+ fatal("Unsupported MIPS target");
}
case EM_PPC:
return new PPCTargetInfo();
@@ -269,7 +269,7 @@ TargetInfo *createTarget() {
case EM_X86_64:
return new X86_64TargetInfo();
}
- error("Unknown target machine");
+ fatal("Unknown target machine");
}
TargetInfo::~TargetInfo() {}
@@ -463,7 +463,7 @@ void X86TargetInfo::relocateOne(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type,
write32le(Loc, Out<ELF32LE>::TlsPhdr->p_memsz - SA);
break;
default:
- error("unrecognized reloc " + Twine(Type));
+ fatal("unrecognized reloc " + Twine(Type));
}
}
@@ -926,7 +926,7 @@ void X86_64TargetInfo::relocateOne(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type,
write32le(Loc, SA - P);
break;
default:
- error("unrecognized reloc " + Twine(Type));
+ fatal("unrecognized reloc " + Twine(Type));
}
}
@@ -969,7 +969,7 @@ void PPCTargetInfo::relocateOne(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type,
write16be(Loc, applyPPCLo(SA));
break;
default:
- error("unrecognized reloc " + Twine(Type));
+ fatal("unrecognized reloc " + Twine(Type));
}
}
@@ -1182,7 +1182,7 @@ void PPC64TargetInfo::relocateOne(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type,
write64be(Loc, SA);
break;
default:
- error("unrecognized reloc " + Twine(Type));
+ fatal("unrecognized reloc " + Twine(Type));
}
}
@@ -1201,7 +1201,7 @@ unsigned AArch64TargetInfo::getDynReloc(unsigned Type) const {
if (Type == R_AARCH64_ABS32 || Type == R_AARCH64_ABS64)
return Type;
StringRef S = getELFRelocationTypeName(EM_AARCH64, Type);
- error("Relocation " + S + " cannot be used when making a shared object; "
+ fatal("Relocation " + S + " cannot be used when making a shared object; "
"recompile with -fPIC.");
}
@@ -1421,7 +1421,7 @@ void AArch64TargetInfo::relocateOne(uint8_t *Loc, uint8_t *BufEnd,
break;
}
default:
- error("unrecognized reloc " + Twine(Type));
+ fatal("unrecognized reloc " + Twine(Type));
}
}
@@ -1472,7 +1472,7 @@ unsigned MipsTargetInfo<ELFT>::getDynReloc(unsigned Type) const {
if (Type == R_MIPS_32 || Type == R_MIPS_64)
return R_MIPS_REL32;
StringRef S = getELFRelocationTypeName(EM_MIPS, Type);
- error("Relocation " + S + " cannot be used when making a shared object; "
+ fatal("Relocation " + S + " cannot be used when making a shared object; "
"recompile with -fPIC.");
}
@@ -1600,7 +1600,7 @@ void MipsTargetInfo<ELFT>::relocateOne(uint8_t *Loc, uint8_t *BufEnd,
break;
}
default:
- error("unrecognized reloc " + Twine(Type));
+ fatal("unrecognized reloc " + Twine(Type));
}
}
diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp
index a616fdc51a9..fa0d1db5234 100644
--- a/lld/ELF/Writer.cpp
+++ b/lld/ELF/Writer.cpp
@@ -162,7 +162,7 @@ template <class ELFT> void Writer<ELFT>::run() {
openFile(Config->OutputFile);
writeHeader();
writeSections();
- error(Buffer->commit());
+ fatal(Buffer->commit());
}
namespace {
@@ -382,7 +382,7 @@ static void reportUndefined(SymbolTable<ELFT> &Symtab, SymbolBody *Sym) {
if (Config->NoInhibitExec)
warning(Msg);
else
- error(Msg);
+ fatal(Msg);
}
template <class ELFT>
@@ -421,7 +421,7 @@ template <class ELFT> void Writer<ELFT>::copyLocalSymbols() {
for (const std::unique_ptr<ObjectFile<ELFT>> &F : Symtab.getObjectFiles()) {
for (const Elf_Sym &Sym : F->getLocalSymbols()) {
ErrorOr<StringRef> SymNameOrErr = Sym.getName(F->getStringTable());
- error(SymNameOrErr);
+ fatal(SymNameOrErr);
StringRef SymName = *SymNameOrErr;
if (!shouldKeepInSymtab<ELFT>(*F, SymName, Sym))
continue;
@@ -1318,7 +1318,7 @@ template <class ELFT> void Writer<ELFT>::writeHeader() {
template <class ELFT> void Writer<ELFT>::openFile(StringRef Path) {
ErrorOr<std::unique_ptr<FileOutputBuffer>> BufferOrErr =
FileOutputBuffer::create(Path, FileSize, FileOutputBuffer::F_executable);
- error(BufferOrErr, "failed to open " + Path);
+ fatal(BufferOrErr, "failed to open " + Path);
Buffer = std::move(*BufferOrErr);
}
OpenPOWER on IntegriCloud