summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRui Ueyama <ruiu@google.com>2016-01-29 01:54:52 +0000
committerRui Ueyama <ruiu@google.com>2016-01-29 01:54:52 +0000
commit1940424632328c9921abf328ede29cbc28f9680c (patch)
treec3c01a5d3874ef36fd4ad936dca396dfe9e99f6f
parent572a6f74a74a1dd668be4a2d00b29a2d50321d02 (diff)
downloadbcm5719-llvm-1940424632328c9921abf328ede29cbc28f9680c.tar.gz
bcm5719-llvm-1940424632328c9921abf328ede29cbc28f9680c.zip
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
-rw-r--r--lld/ELF/Driver.cpp38
-rw-r--r--lld/ELF/Driver.h1
-rw-r--r--lld/ELF/DriverUtils.cpp7
-rw-r--r--lld/ELF/Error.cpp16
-rw-r--r--lld/ELF/Error.h14
-rw-r--r--lld/ELF/LinkerScript.cpp2
-rw-r--r--lld/test/ELF/driver.test9
7 files changed, 59 insertions, 28 deletions
diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp
index a0fc13af472..7909336f44b 100644
--- a/lld/ELF/Driver.cpp
+++ b/lld/ELF/Driver.cpp
@@ -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) {
diff --git a/lld/ELF/Driver.h b/lld/ELF/Driver.h
index 95b6d968c86..adcf4571375 100644
--- a/lld/ELF/Driver.h
+++ b/lld/ELF/Driver.h
@@ -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);
diff --git a/lld/ELF/DriverUtils.cpp b/lld/ELF/DriverUtils.cpp
index 52e463350f0..bbe5f9fc903 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)
- 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.
diff --git a/lld/ELF/Error.cpp b/lld/ELF/Error.cpp
index 327bb26a4f1..e3add1b4068 100644
--- a/lld/ELF/Error.cpp
+++ b/lld/ELF/Error.cpp
@@ -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) {
diff --git a/lld/ELF/Error.h b/lld/ELF/Error.h
index 3b6aa693ec8..546e1d348f2 100644
--- a/lld/ELF/Error.h
+++ b/lld/ELF/Error.h
@@ -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
diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp
index d9f98e9bbff..cbf422d25b4 100644
--- a/lld/ELF/LinkerScript.cpp
+++ b/lld/ELF/LinkerScript.cpp
@@ -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 {
diff --git a/lld/test/ELF/driver.test b/lld/test/ELF/driver.test
new file mode 100644
index 00000000000..13f040e4f9c
--- /dev/null
+++ b/lld/test/ELF/driver.test
@@ -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
OpenPOWER on IntegriCloud