[lld] r267497 - [ELF] Introduce --reproduce flag.

Reid Kleckner via llvm-commits llvm-commits at lists.llvm.org
Tue Apr 26 09:47:47 PDT 2016


My best idea is to add a new lit substitution, like %:t, meaning "the path
%t without the driver separator colon".

On Tue, Apr 26, 2016 at 9:33 AM, Davide Italiano <davide at freebsd.org> wrote:

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


More information about the llvm-commits mailing list