summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRui Ueyama <ruiu@google.com>2016-04-30 22:23:29 +0000
committerRui Ueyama <ruiu@google.com>2016-04-30 22:23:29 +0000
commit9aea957f6d5009db188c6269db7e04f4fce5e31b (patch)
tree986a299b58cbb47941871d657136b666a8c24e44
parent38aa57d966b6e87edc7eb5578c4b2a5b1b8fb522 (diff)
downloadbcm5719-llvm-9aea957f6d5009db188c6269db7e04f4fce5e31b.tar.gz
bcm5719-llvm-9aea957f6d5009db188c6269db7e04f4fce5e31b.zip
ELF: --reproduce: Copy files referenced by linker scripts.
Previuosly, only files appeared on the command line were copied. llvm-svn: 268171
-rw-r--r--lld/ELF/Driver.cpp4
-rw-r--r--lld/ELF/Driver.h4
-rw-r--r--lld/ELF/DriverUtils.cpp22
-rw-r--r--lld/test/ELF/reproduce-linkerscript.s16
4 files changed, 35 insertions, 11 deletions
diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp
index eb3eee522c4..da7ea1c7dfa 100644
--- a/lld/ELF/Driver.cpp
+++ b/lld/ELF/Driver.cpp
@@ -109,6 +109,8 @@ void LinkerDriver::addFile(StringRef Path) {
using namespace llvm::sys::fs;
if (Config->Verbose)
llvm::outs() << Path << "\n";
+ if (!Config->Reproduce.empty())
+ copyInputFile(Path);
Optional<MemoryBufferRef> Buffer = readFile(Path);
if (!Buffer.hasValue())
@@ -252,7 +254,7 @@ void LinkerDriver::main(ArrayRef<const char *> ArgsArr) {
initLLVM(Args);
if (!Config->Reproduce.empty())
- saveLinkerInputs(Args);
+ createResponseFile(Args);
createFiles(Args);
checkOptions(Args);
diff --git a/lld/ELF/Driver.h b/lld/ELF/Driver.h
index 7265de4fd70..3e85c1d35a0 100644
--- a/lld/ELF/Driver.h
+++ b/lld/ELF/Driver.h
@@ -68,7 +68,9 @@ enum {
void printHelp(const char *Argv0);
void printVersion();
-void saveLinkerInputs(const llvm::opt::InputArgList &Args);
+void createResponseFile(const llvm::opt::InputArgList &Args);
+void copyInputFile(StringRef Path);
+
std::string findFromSearchPaths(StringRef Path);
std::string searchLibrary(StringRef Path);
std::string buildSysrootedPath(llvm::StringRef Dir, llvm::StringRef File);
diff --git a/lld/ELF/DriverUtils.cpp b/lld/ELF/DriverUtils.cpp
index 918c29fd143..8174722d22b 100644
--- a/lld/ELF/DriverUtils.cpp
+++ b/lld/ELF/DriverUtils.cpp
@@ -90,7 +90,7 @@ void elf::printVersion() {
// Makes a given pathname an absolute path first, and then remove
// beginning /. For example, "../foo.o" is converted to "home/john/foo.o",
// assuming that the current directory is "/home/john/bar".
-static std::string relative_to_root(StringRef Path) {
+static std::string relativeToRoot(StringRef Path) {
SmallString<128> Abs = Path;
if (std::error_code EC = fs::make_absolute(Abs))
fatal("make_absolute failed: " + EC.message());
@@ -110,20 +110,24 @@ static std::string relative_to_root(StringRef Path) {
return Res.str();
}
-// Copies file Src to {Config->Reproduce}/Src.
-// Returns the new path relative to Config->Reproduce.
-static std::string copyFile(StringRef Src) {
- std::string Relpath = relative_to_root(Src);
+static std::string getDestPath(StringRef Path) {
+ std::string Relpath = relativeToRoot(Path);
SmallString<128> Dest;
path::append(Dest, Config->Reproduce, Relpath);
+ return Dest.str();
+}
+// Copies file Src to {Config->Reproduce}/Src.
+void elf::copyInputFile(StringRef Src) {
+ std::string Dest = getDestPath(Src);
SmallString<128> Dir(Dest);
path::remove_filename(Dir);
- if (std::error_code EC = sys::fs::create_directories(Dir))
+ if (std::error_code EC = sys::fs::create_directories(Dir)) {
error(EC, Dir + ": can't create directory");
+ return;
+ }
if (std::error_code EC = sys::fs::copy_file(Src, Dest))
error(EC, "failed to copy file: " + Dest);
- return Relpath;
}
// Quote a given string if it contains a space character.
@@ -138,7 +142,7 @@ static std::string quote(StringRef S) {
// the same command with the same inputs just by executing
// "ld.lld @response.txt". Used by --reproduce. This feature is
// supposed to be used by users to report an issue to LLD developers.
-void elf::saveLinkerInputs(const llvm::opt::InputArgList &Args) {
+void elf::createResponseFile(const llvm::opt::InputArgList &Args) {
// Create the output directory.
if (std::error_code EC = sys::fs::create_directories(
Config->Reproduce, /*IgnoreExisting=*/false)) {
@@ -165,7 +169,7 @@ void elf::saveLinkerInputs(const llvm::opt::InputArgList &Args) {
case OPT_INPUT: {
StringRef Path = Arg->getValue();
if (fs::exists(Path))
- OS << quote(copyFile(Path)) << "\n";
+ OS << quote(getDestPath(Path)) << "\n";
else
OS << quote(Path) << "\n";
break;
diff --git a/lld/test/ELF/reproduce-linkerscript.s b/lld/test/ELF/reproduce-linkerscript.s
new file mode 100644
index 00000000000..e6a68fe7c2c
--- /dev/null
+++ b/lld/test/ELF/reproduce-linkerscript.s
@@ -0,0 +1,16 @@
+# REQUIRES: x86, shell
+
+# RUN: rm -rf %t.dir
+# RUN: mkdir -p %t.dir/build
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.dir/build/foo.o
+# RUN: echo "INPUT(\"%t.dir/build/foo.o\")" > %t.dir/build/foo.script
+# RUN: cd %t.dir
+# RUN: ld.lld build/foo.script -o bar --reproduce repro
+# RUN: diff build/foo.script repro/%:t.dir/build/foo.script
+# RUN: diff build/foo.o repro/%:t.dir/build/foo.o
+
+.globl _start
+_start:
+ mov $60, %rax
+ mov $42, %rdi
+ syscall
OpenPOWER on IntegriCloud