forked from OSchip/llvm-project
ELF: Report multiple errors from the driver.
This patch let the driver keep going until it parses all command line options. http://reviews.llvm.org/D16645 llvm-svn: 259143
This commit is contained in:
parent
572a6f74a7
commit
1940424632
|
@ -55,8 +55,10 @@ static std::pair<ELFKind, uint16_t> parseEmulation(StringRef S) {
|
|||
if (S == "aarch64linux")
|
||||
return {ELF64LEKind, EM_AARCH64};
|
||||
if (S == "i386pe" || S == "i386pep" || S == "thumb2pe")
|
||||
fatal("Windows targets are not supported on the ELF frontend: " + S);
|
||||
fatal("Unknown emulation: " + S);
|
||||
error("Windows targets are not supported on the ELF frontend: " + S);
|
||||
else
|
||||
error("Unknown emulation: " + S);
|
||||
return {ELFNoneKind, 0};
|
||||
}
|
||||
|
||||
// Returns slices of MB by parsing MB as an archive file.
|
||||
|
@ -84,7 +86,8 @@ void LinkerDriver::addFile(StringRef Path) {
|
|||
if (Config->Verbose)
|
||||
llvm::outs() << Path << "\n";
|
||||
auto MBOrErr = MemoryBuffer::getFile(Path);
|
||||
fatal(MBOrErr, "cannot open " + Path);
|
||||
if (error(MBOrErr, "cannot open " + Path))
|
||||
return;
|
||||
std::unique_ptr<MemoryBuffer> &MB = *MBOrErr;
|
||||
MemoryBufferRef MBRef = MB->getMemBufferRef();
|
||||
OwningMBs.push_back(std::move(MB)); // take MB ownership
|
||||
|
@ -109,6 +112,15 @@ void LinkerDriver::addFile(StringRef Path) {
|
|||
}
|
||||
}
|
||||
|
||||
// Add a given library by searching it from input search paths.
|
||||
void LinkerDriver::addLibrary(StringRef Name) {
|
||||
StringRef Path = searchLibrary(Name);
|
||||
if (Path.empty())
|
||||
error("Unable to find library -l" + Name);
|
||||
else
|
||||
addFile(Path);
|
||||
}
|
||||
|
||||
// Some command line options or some combinations of them are not allowed.
|
||||
// This function checks for such errors.
|
||||
static void checkOptions(opt::InputArgList &Args) {
|
||||
|
@ -116,15 +128,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))
|
||||
fatal("-r option is not supported. Use 'ar' command instead.");
|
||||
error("-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)
|
||||
fatal("The .gnu.hash section is not compatible with the MIPS target.");
|
||||
error("The .gnu.hash section is not compatible with the MIPS target.");
|
||||
|
||||
if (Config->EMachine == EM_AMDGPU && !Config->Entry.empty())
|
||||
fatal("-e option is not valid for AMDGPU.");
|
||||
error("-e option is not valid for AMDGPU.");
|
||||
}
|
||||
|
||||
static StringRef
|
||||
|
@ -148,6 +160,8 @@ void LinkerDriver::main(ArrayRef<const char *> ArgsArr) {
|
|||
readConfigs(Args);
|
||||
createFiles(Args);
|
||||
checkOptions(Args);
|
||||
if (HasError)
|
||||
return;
|
||||
|
||||
switch (Config->EKind) {
|
||||
case ELF32LEKind:
|
||||
|
@ -163,7 +177,7 @@ void LinkerDriver::main(ArrayRef<const char *> ArgsArr) {
|
|||
link<ELF64BE>(Args);
|
||||
return;
|
||||
default:
|
||||
fatal("-m or at least a .o file required");
|
||||
error("-m or at least a .o file required");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -219,7 +233,7 @@ void LinkerDriver::readConfigs(opt::InputArgList &Args) {
|
|||
if (auto *Arg = Args.getLastArg(OPT_O)) {
|
||||
StringRef Val = Arg->getValue();
|
||||
if (Val.getAsInteger(10, Config->Optimize))
|
||||
fatal("Invalid optimization level");
|
||||
error("Invalid optimization level");
|
||||
}
|
||||
|
||||
if (auto *Arg = Args.getLastArg(OPT_hash_style)) {
|
||||
|
@ -230,7 +244,7 @@ void LinkerDriver::readConfigs(opt::InputArgList &Args) {
|
|||
} else if (S == "both") {
|
||||
Config->GnuHash = true;
|
||||
} else if (S != "sysv")
|
||||
fatal("Unknown hash style: " + S);
|
||||
error("Unknown hash style: " + S);
|
||||
}
|
||||
|
||||
for (auto *Arg : Args.filtered(OPT_undefined))
|
||||
|
@ -241,7 +255,7 @@ void LinkerDriver::createFiles(opt::InputArgList &Args) {
|
|||
for (auto *Arg : Args) {
|
||||
switch (Arg->getOption().getID()) {
|
||||
case OPT_l:
|
||||
addFile(searchLibrary(Arg->getValue()));
|
||||
addLibrary(Arg->getValue());
|
||||
break;
|
||||
case OPT_INPUT:
|
||||
case OPT_script:
|
||||
|
@ -268,8 +282,8 @@ void LinkerDriver::createFiles(opt::InputArgList &Args) {
|
|||
}
|
||||
}
|
||||
|
||||
if (Files.empty())
|
||||
fatal("no input files.");
|
||||
if (Files.empty() && !HasError)
|
||||
error("no input files.");
|
||||
}
|
||||
|
||||
template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) {
|
||||
|
|
|
@ -27,6 +27,7 @@ class LinkerDriver {
|
|||
public:
|
||||
void main(ArrayRef<const char *> Args);
|
||||
void addFile(StringRef Path);
|
||||
void addLibrary(StringRef Name);
|
||||
|
||||
private:
|
||||
void readConfigs(llvm::opt::InputArgList &Args);
|
||||
|
|
|
@ -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)
|
||||
fatal(Twine("missing arg value for \"") + Args.getArgString(MissingIndex) +
|
||||
error(Twine("missing arg value for \"") + Args.getArgString(MissingIndex) +
|
||||
"\", expected " + Twine(MissingCount) +
|
||||
(MissingCount == 1 ? " argument.\n" : " arguments"));
|
||||
|
||||
|
@ -74,8 +74,7 @@ opt::InputArgList elf2::parseArgs(llvm::BumpPtrAllocator *A,
|
|||
for (auto *Arg : Unknowns)
|
||||
warning("warning: unknown argument: " + Arg->getSpelling());
|
||||
if (Unknowns.begin() != Unknowns.end())
|
||||
fatal("unknown argument(s) found");
|
||||
|
||||
error("unknown argument(s) found");
|
||||
return Args;
|
||||
}
|
||||
|
||||
|
@ -104,7 +103,7 @@ std::string elf2::searchLibrary(StringRef Path) {
|
|||
if (!S.empty())
|
||||
return S;
|
||||
}
|
||||
fatal("Unable to find library -l" + Path);
|
||||
return "";
|
||||
}
|
||||
|
||||
// Makes a path by concatenating Dir and File.
|
||||
|
|
|
@ -24,14 +24,18 @@ void error(const Twine &Msg) {
|
|||
HasError = true;
|
||||
}
|
||||
|
||||
void error(std::error_code EC, const Twine &Prefix) {
|
||||
if (EC)
|
||||
error(Prefix + ": " + EC.message());
|
||||
bool error(std::error_code EC, const Twine &Prefix) {
|
||||
if (!EC)
|
||||
return false;
|
||||
error(Prefix + ": " + EC.message());
|
||||
return true;
|
||||
}
|
||||
|
||||
void error(std::error_code EC) {
|
||||
if (EC)
|
||||
error(EC.message());
|
||||
bool error(std::error_code EC) {
|
||||
if (!EC)
|
||||
return false;
|
||||
error(EC.message());
|
||||
return true;
|
||||
}
|
||||
|
||||
void fatal(const Twine &Msg) {
|
||||
|
|
|
@ -20,13 +20,16 @@ extern bool HasError;
|
|||
void warning(const Twine &Msg);
|
||||
|
||||
void error(const Twine &Msg);
|
||||
void error(std::error_code EC, const Twine &Prefix);
|
||||
void error(std::error_code EC);
|
||||
bool error(std::error_code EC, const Twine &Prefix);
|
||||
bool error(std::error_code EC);
|
||||
|
||||
template <typename T> void error(const ErrorOr<T> &V, const Twine &Prefix) {
|
||||
error(V.getError(), Prefix);
|
||||
template <typename T> bool error(const ErrorOr<T> &V, const Twine &Prefix) {
|
||||
return error(V.getError(), Prefix);
|
||||
}
|
||||
|
||||
template <typename T> bool error(const ErrorOr<T> &V) {
|
||||
return error(V.getError());
|
||||
}
|
||||
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);
|
||||
|
@ -35,6 +38,7 @@ 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
|
||||
|
|
|
@ -178,7 +178,7 @@ void LinkerScript::addFile(StringRef S) {
|
|||
else
|
||||
Driver->addFile(Saver.save(Config->Sysroot + "/" + S.substr(1)));
|
||||
} else if (S.startswith("-l")) {
|
||||
Driver->addFile(searchLibrary(S.substr(2)));
|
||||
Driver->addLibrary(S.substr(2));
|
||||
} else if (sys::fs::exists(S)) {
|
||||
Driver->addFile(S);
|
||||
} else {
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
# RUN: not ld.lld -unknown1 -unknown2 -m foo /no/such/file -lnosuchlib \
|
||||
# RUN: 2>&1 | FileCheck %s
|
||||
|
||||
# CHECK: warning: unknown argument: -unknown1
|
||||
# CHECK: warning: unknown argument: -unknown2
|
||||
# CHECK: unknown argument(s) found
|
||||
# CHECK: Unknown emulation: foo
|
||||
# CHECK: cannot open /no/such/file
|
||||
# CHECK: Unable to find library -lnosuchlib
|
Loading…
Reference in New Issue