forked from OSchip/llvm-project
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
This commit is contained in:
parent
ec8d086c64
commit
64cfffd333
|
@ -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) {
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -125,7 +125,7 @@ void link(llvm::ArrayRef<const char *> args);
|
|||
}
|
||||
|
||||
namespace elf2 {
|
||||
void link(llvm::ArrayRef<const char *> args);
|
||||
bool link(llvm::ArrayRef<const char *> args);
|
||||
}
|
||||
|
||||
/// Driver for lld unit tests
|
||||
|
|
|
@ -205,8 +205,7 @@ bool UniversalDriver::link(llvm::MutableArrayRef<const char *> args,
|
|||
case Flavor::old_gnu_ld:
|
||||
return GnuLdDriver::linkELF(args, diagnostics);
|
||||
case Flavor::gnu_ld:
|
||||
elf2::link(args);
|
||||
return true;
|
||||
return elf2::link(args);
|
||||
case Flavor::darwin_ld:
|
||||
return DarwinLdDriver::linkMachO(args, diagnostics);
|
||||
case Flavor::win_link:
|
||||
|
|
Loading…
Reference in New Issue