<div dir="ltr">My best idea is to add a new lit substitution, like %:t, meaning "the path %t without the driver separator colon".</div><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Apr 26, 2016 at 9:33 AM, Davide Italiano <span dir="ltr"><<a href="mailto:davide@freebsd.org" target="_blank">davide@freebsd.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="HOEnZb"><div class="h5">On Mon, Apr 25, 2016 at 6:56 PM, Sean Silva <<a href="mailto:chisophugis@gmail.com">chisophugis@gmail.com</a>> wrote:<br>
><br>
><br>
> On Mon, Apr 25, 2016 at 5:22 PM, Davide Italiano via llvm-commits<br>
> <<a href="mailto:llvm-commits@lists.llvm.org">llvm-commits@lists.llvm.org</a>> wrote:<br>
>><br>
>> Author: davide<br>
>> Date: Mon Apr 25 19:22:24 2016<br>
>> New Revision: 267497<br>
>><br>
>> URL: <a href="http://llvm.org/viewvc/llvm-project?rev=267497&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=267497&view=rev</a><br>
>> Log:<br>
>> [ELF] Introduce --reproduce flag.<br>
>><br>
>> --reproduce dumps the object files in a directory chosen<br>
>> (preserving the file system layout) and the linker invocation<br>
>> so that people can create an archive and upload for debugging.<br>
>><br>
>> Differential Revision:  <a href="http://reviews.llvm.org/D19494" rel="noreferrer" target="_blank">http://reviews.llvm.org/D19494</a><br>
>><br>
>> Added:<br>
>>     lld/trunk/test/ELF/reproduce.s<br>
>> Modified:<br>
>>     lld/trunk/ELF/Config.h<br>
>>     lld/trunk/ELF/Driver.cpp<br>
>>     lld/trunk/ELF/Options.td<br>
>><br>
>> Modified: lld/trunk/ELF/Config.h<br>
>> URL:<br>
>> <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Config.h?rev=267497&r1=267496&r2=267497&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Config.h?rev=267497&r1=267496&r2=267497&view=diff</a><br>
>><br>
>> ==============================================================================<br>
>> --- lld/trunk/ELF/Config.h (original)<br>
>> +++ lld/trunk/ELF/Config.h Mon Apr 25 19:22:24 2016<br>
>> @@ -48,6 +48,7 @@ struct Configuration {<br>
>>    llvm::StringRef SoName;<br>
>>    llvm::StringRef Sysroot;<br>
>>    std::string RPath;<br>
>> +  std::string Reproduce;<br>
>>    std::vector<llvm::StringRef> DynamicList;<br>
>>    std::vector<llvm::StringRef> SearchPaths;<br>
>>    std::vector<llvm::StringRef> Undefined;<br>
>><br>
>> Modified: lld/trunk/ELF/Driver.cpp<br>
>> URL:<br>
>> <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Driver.cpp?rev=267497&r1=267496&r2=267497&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Driver.cpp?rev=267497&r1=267496&r2=267497&view=diff</a><br>
>><br>
>> ==============================================================================<br>
>> --- lld/trunk/ELF/Driver.cpp (original)<br>
>> +++ lld/trunk/ELF/Driver.cpp Mon Apr 25 19:22:24 2016<br>
>> @@ -19,6 +19,7 @@<br>
>>  #include "Writer.h"<br>
>>  #include "lld/Driver/Driver.h"<br>
>>  #include "llvm/ADT/StringExtras.h"<br>
>> +#include "llvm/Support/Path.h"<br>
>>  #include "llvm/Support/TargetSelect.h"<br>
>>  #include "llvm/Support/raw_ostream.h"<br>
>>  #include <utility><br>
>> @@ -97,12 +98,29 @@ LinkerDriver::getArchiveMembers(MemoryBu<br>
>>    return V;<br>
>>  }<br>
>><br>
>> +static void dumpFile(StringRef SrcPath) {<br>
>> +  SmallString<128> DirName;<br>
>> +  sys::path::append(DirName, Config->Reproduce,<br>
>> sys::path::parent_path(SrcPath));<br>
>> +  if (std::error_code EC = sys::fs::create_directories(DirName)) {<br>
>> +    error(EC, "--reproduce: can't create directory");<br>
>> +    return;<br>
>> +  }<br>
>> +<br>
>> +  SmallString<128> DestPathName;<br>
>> +  sys::path::append(DestPathName, Config->Reproduce, SrcPath);<br>
>> +  if (std::error_code EC = sys::fs::copy_file(SrcPath, DestPathName))<br>
>> +    error(EC, "--reproduce: can't copy file");<br>
>> +}<br>
>> +<br>
>>  // Opens and parses a file. Path has to be resolved already.<br>
>>  // Newly created memory buffers are owned by this driver.<br>
>>  void LinkerDriver::addFile(StringRef Path) {<br>
>>    using namespace llvm::sys::fs;<br>
>>    if (Config->Verbose)<br>
>>      llvm::outs() << Path << "\n";<br>
>> +  if (!Config->Reproduce.empty())<br>
>> +    dumpFile(Path);<br>
>> +<br>
>>    Optional<MemoryBufferRef> Buffer = readFile(Path);<br>
>>    if (!Buffer.hasValue())<br>
>>      return;<br>
>> @@ -223,6 +241,25 @@ static bool hasZOption(opt::InputArgList<br>
>>    return false;<br>
>>  }<br>
>><br>
>> +static void dumpLinkerInvocation(ArrayRef<const char *> Args) {<br>
>> +  std::error_code EC = sys::fs::create_directories(Config->Reproduce,<br>
>> +    false /* IgnoreExisting */);<br>
>> +  if (EC) {<br>
>> +    error(EC, "--reproduce: can't create directory");<br>
>> +    return;<br>
>> +  }<br>
>> +<br>
>> +  SmallString<128> InvocationPath;<br>
>> +  sys::path::append(InvocationPath, Config->Reproduce, "invocation.txt");<br>
>> +  raw_fd_ostream OS(InvocationPath, EC, sys::fs::OpenFlags::F_None);<br>
>> +  check(EC);<br>
>> +<br>
>> +  OS << Args[0];<br>
>> +  for (unsigned I = 1, E = Args.size(); I < E; ++I)<br>
>> +    OS << " " << Args[I];<br>
>> +  OS << "\n";<br>
>> +}<br>
>> +<br>
>>  void LinkerDriver::main(ArrayRef<const char *> ArgsArr) {<br>
>>    ELFOptTable Parser;<br>
>>    opt::InputArgList Args = Parser.parse(ArgsArr.slice(1));<br>
>> @@ -237,6 +274,10 @@ void LinkerDriver::main(ArrayRef<const c<br>
>><br>
>>    initLLVM(Args);<br>
>>    readConfigs(Args);<br>
>> +<br>
>> +  if (!Config->Reproduce.empty())<br>
>> +    dumpLinkerInvocation(ArgsArr);<br>
>> +<br>
>>    createFiles(Args);<br>
>>    checkOptions(Args);<br>
>>    if (HasError)<br>
>> @@ -311,6 +352,8 @@ void LinkerDriver::readConfigs(opt::Inpu<br>
>>    Config->Fini = getString(Args, OPT_fini, "_fini");<br>
>>    Config->Init = getString(Args, OPT_init, "_init");<br>
>>    Config->OutputFile = getString(Args, OPT_o);<br>
>> +  if (auto *Arg = Args.getLastArg(OPT_reproduce))<br>
>> +    Config->Reproduce = Arg->getValue();<br>
>>    Config->SoName = getString(Args, OPT_soname);<br>
>>    Config->Sysroot = getString(Args, OPT_sysroot);<br>
>><br>
>><br>
>> Modified: lld/trunk/ELF/Options.td<br>
>> URL:<br>
>> <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Options.td?rev=267497&r1=267496&r2=267497&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Options.td?rev=267497&r1=267496&r2=267497&view=diff</a><br>
>><br>
>> ==============================================================================<br>
>> --- lld/trunk/ELF/Options.td (original)<br>
>> +++ lld/trunk/ELF/Options.td Mon Apr 25 19:22:24 2016<br>
>> @@ -120,6 +120,9 @@ def pie : Flag<["-"], "pie">,<br>
>>  def print_gc_sections: Flag<["--"], "print-gc-sections">,<br>
>>    HelpText<"List removed unused sections">;<br>
>><br>
>> +def reproduce : Separate<["--"], "reproduce">,<br>
>> +  HelpText<"Dump linker invocation and input files for debugging">;<br>
>> +<br>
>>  def rpath : Separate<["-"], "rpath">,<br>
>>    HelpText<"Add a DT_RUNPATH to the output">;<br>
>><br>
>><br>
>> Added: lld/trunk/test/ELF/reproduce.s<br>
>> URL:<br>
>> <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/reproduce.s?rev=267497&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/reproduce.s?rev=267497&view=auto</a><br>
>><br>
>> ==============================================================================<br>
>> --- lld/trunk/test/ELF/reproduce.s (added)<br>
>> +++ lld/trunk/test/ELF/reproduce.s Mon Apr 25 19:22:24 2016<br>
>> @@ -0,0 +1,26 @@<br>
>> +# REQUIRES: x86<br>
>> +<br>
>> +# RUN: rm -rf %S/repro<br>
>> +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t<br>
>> +# RUN: ld.lld %t -o %t2 -shared --as-needed --reproduce %S/repro<br>
>> +# RUN: llvm-objdump -d %S/repro/%t | FileCheck %s --check-prefix=DUMP<br>
>> +# RUN: cat %S/repro/invocation.txt | FileCheck %s<br>
>> --check-prefix=INVOCATION<br>
>> +<br>
>> +.globl _start;<br>
>> +_start:<br>
>> +  mov $60, %rax<br>
>> +  mov $42, %rdi<br>
>> +  syscall<br>
>> +<br>
>> +# DUMP: Disassembly of section .text:<br>
>> +# DUMP: _start:<br>
>> +# DUMP:        0:       48 c7 c0 3c 00 00 00    movq    $60, %rax<br>
>> +# DUMP:        7:       48 c7 c7 2a 00 00 00    movq    $42, %rdi<br>
>> +# DUMP:        e:       0f 05   syscall<br>
>> +<br>
>> +# INVOCATION: lld {{.*}}reproduce.s{{.*}} -o {{.*}} -shared --as-needed<br>
>> --reproduce<br>
>> +<br>
>> +# RUN: rm -rf %S/repro2<br>
>> +# RUN: mkdir %S/repro2<br>
><br>
><br>
> You probably want `%t.dir` or something like that instead of `%S` so that<br>
> you avoid littering files in the source directory.<br>
><br>
> -- Sean Silva<br>
><br>
>><br>
>> +# RUN: not ld.lld %t -o %t2 --reproduce %S/repro2 2>&1 | FileCheck<br>
>> --check-prefix=EDIR %s<br>
>> +# EDIR: --reproduce: can't create directory<br>
>><br>
>><br>
>> _______________________________________________<br>
>> llvm-commits mailing list<br>
>> <a href="mailto:llvm-commits@lists.llvm.org">llvm-commits@lists.llvm.org</a><br>
>> <a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</a><br>
><br>
><br>
<br>
</div></div>Addressed both your concerns.<br>
BTW, there's a problem I'm not still able to figure out (which<br>
prevents this test to be enabled on Windows), and I'd like to hear<br>
others' opinions.<br>
My experience on Windows is fairly limited, so, maybe, the solution is<br>
obvious to some of you.<br>
<br>
Currently the test runs llvm-objdump like this:<br>
<br>
 llvm-objdump -d %t.dir/repro/%t<br>
<br>
%t will expand to c:/... so the path will contain two drive letters<br>
(making it invalid).<br>
I can transform the path in lld, e.g. replacing c: -> /c, but I'm not<br>
entirely sure what's the correct way to handle this case in the test<br>
(without hardcoding the path).<br>
Any ideas?<br>
<br>
Thanks!<br>
<span class="HOEnZb"><font color="#888888"><br>
--<br>
Davide<br>
<br>
"There are no solved problems; there are only problems that are more<br>
or less solved" -- Henri Poincare<br>
</font></span></blockquote></div><br></div>