summaryrefslogtreecommitdiffstats
path: root/lld/ELF/Driver.cpp
diff options
context:
space:
mode:
authorRui Ueyama <ruiu@google.com>2016-04-26 20:36:46 +0000
committerRui Ueyama <ruiu@google.com>2016-04-26 20:36:46 +0000
commit673b609586c1ae7a61108342ec6353989bee1497 (patch)
tree984ea54596040b05eb18783b7e2ca371d3a7b014 /lld/ELF/Driver.cpp
parent2f1459cbb7d7c37223ed0a52df11af8425e26599 (diff)
downloadbcm5719-llvm-673b609586c1ae7a61108342ec6353989bee1497.tar.gz
bcm5719-llvm-673b609586c1ae7a61108342ec6353989bee1497.zip
Handle Windows drive letters and ".." for --reproduce.
When --reproduce <path> is given, then we need to concatenate input file paths to the given path to save input files to the directory. Previously, path concatenation didn't handle Windows drive letters so it could generate invalid paths such as "C:\D:\foo". It also didn't handle ".." path components, so it could produce some bad paths such as "foo/../../etc/passwd". In this patch, Windows drive letters and ".." are removed before concatenating paths. Differential Revision: http://reviews.llvm.org/D19551 llvm-svn: 267600
Diffstat (limited to 'lld/ELF/Driver.cpp')
-rw-r--r--lld/ELF/Driver.cpp56
1 files changed, 35 insertions, 21 deletions
diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp
index 5af45acf48d..8e8ab7f6b47 100644
--- a/lld/ELF/Driver.cpp
+++ b/lld/ELF/Driver.cpp
@@ -27,6 +27,7 @@
using namespace llvm;
using namespace llvm::ELF;
using namespace llvm::object;
+using namespace llvm::sys;
using namespace lld;
using namespace lld::elf;
@@ -98,18 +99,31 @@ LinkerDriver::getArchiveMembers(MemoryBufferRef MB) {
return V;
}
-static void dumpFile(StringRef SrcPath) {
- SmallString<128> DirName;
- sys::path::append(DirName, Config->Reproduce, sys::path::parent_path(SrcPath));
- if (std::error_code EC = sys::fs::create_directories(DirName)) {
- error(EC, "--reproduce: can't create directory");
+// Concatenates S and T so that the resulting path becomes S/T.
+// There are a few exceptions:
+//
+// 1. The result will never escape from S. Therefore, all ".."
+// are removed from T before concatenatig them.
+// 2. Windows drive letters are removed from T before concatenation.
+static std::string concat(StringRef S, StringRef T) {
+ // Remove leading '/' or a drive letter, and then remove "..".
+ SmallString<128> T2(path::relative_path(T));
+ path::remove_dots(T2, /*remove_dot_dot=*/true);
+
+ SmallString<128> Res;
+ path::append(Res, S, T2);
+ return Res.str();
+}
+
+static void copyFile(StringRef Src, StringRef Dest) {
+ SmallString<128> Dir(Dest);
+ path::remove_filename(Dir);
+ if (std::error_code EC = sys::fs::create_directories(Dir)) {
+ error(EC, Dir + ": can't create directory");
return;
}
-
- SmallString<128> DestPathName;
- sys::path::append(DestPathName, Config->Reproduce, SrcPath);
- if (std::error_code EC = sys::fs::copy_file(SrcPath, DestPathName))
- error(EC, "--reproduce: can't copy file");
+ if (std::error_code EC = sys::fs::copy_file(Src, Dest))
+ error(EC, "failed to copy file: " + Dest);
}
// Opens and parses a file. Path has to be resolved already.
@@ -119,7 +133,7 @@ void LinkerDriver::addFile(StringRef Path) {
if (Config->Verbose)
llvm::outs() << Path << "\n";
if (!Config->Reproduce.empty())
- dumpFile(Path);
+ copyFile(Path, concat(Config->Reproduce, Path));
Optional<MemoryBufferRef> Buffer = readFile(Path);
if (!Buffer.hasValue())
@@ -241,21 +255,21 @@ static bool hasZOption(opt::InputArgList &Args, StringRef Key) {
return false;
}
-static void dumpLinkerInvocation(ArrayRef<const char *> Args) {
- std::error_code EC = sys::fs::create_directories(Config->Reproduce,
- false /* IgnoreExisting */);
- if (EC) {
- error(EC, "--reproduce: can't create directory");
+static void logCommandline(ArrayRef<const char *> Args) {
+ if (std::error_code EC = sys::fs::create_directories(
+ Config->Reproduce, /*IgnoreExisting=*/false)) {
+ error(EC, Config->Reproduce + ": can't create directory");
return;
}
- SmallString<128> InvocationPath;
- sys::path::append(InvocationPath, Config->Reproduce, "invocation.txt");
- raw_fd_ostream OS(InvocationPath, EC, sys::fs::OpenFlags::F_None);
+ SmallString<128> Path;
+ path::append(Path, Config->Reproduce, "invocation.txt");
+ std::error_code EC;
+ raw_fd_ostream OS(Path, EC, sys::fs::OpenFlags::F_None);
check(EC);
OS << Args[0];
- for (unsigned I = 1, E = Args.size(); I < E; ++I)
+ for (size_t I = 1, E = Args.size(); I < E; ++I)
OS << " " << Args[I];
OS << "\n";
}
@@ -276,7 +290,7 @@ void LinkerDriver::main(ArrayRef<const char *> ArgsArr) {
readConfigs(Args);
if (!Config->Reproduce.empty())
- dumpLinkerInvocation(ArgsArr);
+ logCommandline(ArgsArr);
createFiles(Args);
checkOptions(Args);
OpenPOWER on IntegriCloud