[lld] r269593 - Reorganize the cpio archiver as CpioFile class. NFC.
Rui Ueyama via llvm-commits
llvm-commits at lists.llvm.org
Sun May 15 10:10:23 PDT 2016
Author: ruiu
Date: Sun May 15 12:10:23 2016
New Revision: 269593
URL: http://llvm.org/viewvc/llvm-project?rev=269593&view=rev
Log:
Reorganize the cpio archiver as CpioFile class. NFC.
This code separates the code to create cpio archive from the driver.
Modified:
lld/trunk/ELF/Config.h
lld/trunk/ELF/Driver.cpp
lld/trunk/ELF/Driver.h
lld/trunk/ELF/DriverUtils.cpp
lld/trunk/ELF/InputFiles.cpp
Modified: lld/trunk/ELF/Config.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Config.h?rev=269593&r1=269592&r2=269593&view=diff
==============================================================================
--- lld/trunk/ELF/Config.h (original)
+++ lld/trunk/ELF/Config.h Sun May 15 12:10:23 2016
@@ -48,7 +48,6 @@ 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=269593&r1=269592&r2=269593&view=diff
==============================================================================
--- lld/trunk/ELF/Driver.cpp (original)
+++ lld/trunk/ELF/Driver.cpp Sun May 15 12:10:23 2016
@@ -114,7 +114,8 @@ void LinkerDriver::addFile(StringRef Pat
return;
MemoryBufferRef MBRef = *Buffer;
- maybeCopyInputFile(Path, MBRef.getBuffer());
+ if (Cpio)
+ Cpio->append(relativeToRoot(Path), MBRef.getBuffer());
switch (identify_magic(MBRef.getBuffer())) {
case file_magic::unknown:
@@ -252,15 +253,12 @@ void LinkerDriver::main(ArrayRef<const c
readConfigs(Args);
initLLVM(Args);
- if (!Config->Reproduce.empty()) {
- std::error_code EC;
- std::string File = Config->Reproduce + ".cpio";
- ReproduceArchive = llvm::make_unique<raw_fd_ostream>(File, EC, fs::F_None);
- if (EC) {
- error(EC, "--reproduce: failed to open " + File);
- return;
- }
- createResponseFile(Args);
+ if (auto *Arg = Args.getLastArg(OPT_reproduce)) {
+ // Note that --reproduce is a debug option so you can ignore it
+ // if you are trying to understand the whole picture of the code.
+ Cpio.reset(CpioFile::create(Arg->getValue()));
+ if (Cpio)
+ Cpio->append("response.txt", createResponseFile(Args));
}
createFiles(Args);
@@ -340,7 +338,6 @@ 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);
- Config->Reproduce = getString(Args, OPT_reproduce);
Config->SoName = getString(Args, OPT_soname);
Config->Sysroot = getString(Args, OPT_sysroot);
Modified: lld/trunk/ELF/Driver.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Driver.h?rev=269593&r1=269592&r2=269593&view=diff
==============================================================================
--- lld/trunk/ELF/Driver.h (original)
+++ lld/trunk/ELF/Driver.h Sun May 15 12:10:23 2016
@@ -23,16 +23,15 @@ namespace elf {
extern class LinkerDriver *Driver;
+class CpioFile;
+
class LinkerDriver {
public:
void main(ArrayRef<const char *> Args);
void addFile(StringRef Path);
void addLibrary(StringRef Name);
- llvm::LLVMContext Context;
-
- // for --reproduce
- std::unique_ptr<llvm::raw_fd_ostream> ReproduceArchive;
- llvm::StringSet<> IncludedFiles;
+ llvm::LLVMContext Context; // to parse bitcode ifles
+ std::unique_ptr<CpioFile> Cpio; // for reproduce
private:
std::vector<MemoryBufferRef> getArchiveMembers(MemoryBufferRef MB);
@@ -70,12 +69,37 @@ enum {
#undef OPTION
};
+// This is the class to create a .cpio file for --reproduce.
+//
+// If "--reproduce foo" is given, we create a file "foo.cpio" and
+// copy all input files to the archive, along with a response file
+// to re-run the same command with the same inputs.
+// It is useful for reporting issues to LLD developers.
+//
+// Cpio as a file format is a deliberate choice. It's standardized in
+// POSIX and very easy to create. cpio command is available virtually
+// on all Unix systems. See
+// http://pubs.opengroup.org/onlinepubs/9699919799/utilities/pax.html#tag_20_92_13_07
+// for the format details.
+class CpioFile {
+public:
+ static CpioFile *create(StringRef OutputPath);
+ void append(StringRef Path, StringRef Data);
+
+private:
+ CpioFile(std::unique_ptr<llvm::raw_fd_ostream> OS, StringRef Basename);
+
+ std::unique_ptr<llvm::raw_fd_ostream> OS;
+ llvm::StringSet<> Seen;
+ std::string Basename;
+};
+
void printHelp(const char *Argv0);
void printVersion();
std::vector<uint8_t> parseHexstring(StringRef S);
-void createResponseFile(const llvm::opt::InputArgList &Args);
-void maybeCopyInputFile(StringRef Path, StringRef Buffer);
+std::string createResponseFile(const llvm::opt::InputArgList &Args);
+std::string relativeToRoot(StringRef Path);
std::string findFromSearchPaths(StringRef Path);
std::string searchLibrary(StringRef Path);
Modified: lld/trunk/ELF/DriverUtils.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/DriverUtils.cpp?rev=269593&r1=269592&r2=269593&view=diff
==============================================================================
--- lld/trunk/ELF/DriverUtils.cpp (original)
+++ lld/trunk/ELF/DriverUtils.cpp Sun May 15 12:10:23 2016
@@ -107,7 +107,7 @@ std::vector<uint8_t> elf::parseHexstring
// 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 relativeToRoot(StringRef Path) {
+std::string elf::relativeToRoot(StringRef Path) {
SmallString<128> Abs = Path;
if (std::error_code EC = fs::make_absolute(Abs))
fatal("make_absolute failed: " + EC.message());
@@ -127,22 +127,26 @@ static std::string relativeToRoot(String
return Res.str();
}
-static std::string getDestPath(StringRef Path) {
- std::string Relpath = relativeToRoot(Path);
- SmallString<128> Dest;
- path::append(Dest, path::filename(Config->Reproduce), Relpath);
- return Dest.str();
-}
+CpioFile::CpioFile(std::unique_ptr<llvm::raw_fd_ostream> OS, StringRef S)
+ : OS(std::move(OS)), Basename(S) {}
-static void maybePrintCpioMemberAux(raw_fd_ostream &OS, StringRef Path,
- StringRef Data) {
- OS << "070707"; // c_magic
-
- // The c_dev/c_ino pair should be unique according to the spec, but no one
- // seems to care.
- OS << "000000"; // c_dev
- OS << "000000"; // c_ino
+CpioFile *CpioFile::create(StringRef OutputPath) {
+ std::string Path = (OutputPath + ".cpio").str();
+ std::error_code EC;
+ auto OS = llvm::make_unique<raw_fd_ostream>(Path, EC, fs::F_None);
+ if (EC) {
+ error(EC, "--reproduce: failed to open " + Path);
+ return nullptr;
+ }
+ return new CpioFile(std::move(OS), path::filename(OutputPath));
+}
+static void writeMember(raw_fd_ostream &OS, StringRef Path, StringRef Data) {
+ // The c_dev/c_ino pair should be unique according to the spec,
+ // but no one seems to care.
+ OS << "070707"; // c_magic
+ OS << "000000"; // c_dev
+ OS << "000000"; // c_ino
OS << "100664"; // c_mode: C_ISREG | rw-rw-r--
OS << "000000"; // c_uid
OS << "000000"; // c_gid
@@ -155,28 +159,22 @@ static void maybePrintCpioMemberAux(raw_
OS << Data; // c_filedata
}
-static void maybePrintCpioMember(StringRef Path, StringRef Data) {
- if (Config->Reproduce.empty())
+void CpioFile::append(StringRef Path, StringRef Data) {
+ if (!Seen.insert(Path).second)
return;
- if (!Driver->IncludedFiles.insert(Path).second)
- return;
- raw_fd_ostream &OS = *Driver->ReproduceArchive;
- maybePrintCpioMemberAux(OS, Path, Data);
-
- // Print the trailer and seek back. This way we have a valid archive if we
- // crash.
- // See http://pubs.opengroup.org/onlinepubs/9699919799/utilities/pax.html#tag_20_92_13_11
- // for the format details.
- uint64_t Pos = OS.tell();
- maybePrintCpioMemberAux(OS, "TRAILER!!!", "");
- OS.seek(Pos);
-}
-
-// Write file Src with content Data to the archive.
-void elf::maybeCopyInputFile(StringRef Src, StringRef Data) {
- std::string Dest = getDestPath(Src);
- maybePrintCpioMember(Dest, Data);
+ // Construct an in-archive filename so that /home/foo/bar is stored
+ // as baz/home/foo/bar where baz is the basename of the output file.
+ // (i.e. in that case we are creating baz.cpio.)
+ SmallString<128> Fullpath;
+ path::append(Fullpath, Basename, Path);
+ writeMember(*OS, Fullpath, Data);
+
+ // Print the trailer and seek back.
+ // This way we have a valid archive if we crash.
+ uint64_t Pos = OS->tell();
+ writeMember(*OS, "TRAILER!!!", "");
+ OS->seek(Pos);
}
// Quote a given string if it contains a space character.
@@ -202,15 +200,13 @@ static std::string stringize(opt::Arg *A
return K + " " + V;
}
-// Copies all input files to Config->Reproduce directory and
-// create a response file as "response.txt", so that you can re-run
-// 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::createResponseFile(const opt::InputArgList &Args) {
+// Reconstructs command line arguments so that so that you can re-run
+// the same command with the same inputs. This is for --reproduce.
+std::string elf::createResponseFile(const opt::InputArgList &Args) {
SmallString<0> Data;
raw_svector_ostream OS(Data);
- // Copy the command line to response.txt while rewriting paths.
+
+ // Copy the command line to the output while rewriting paths.
for (auto *Arg : Args) {
switch (Arg->getOption().getID()) {
case OPT_reproduce:
@@ -230,10 +226,7 @@ void elf::createResponseFile(const opt::
OS << stringize(Arg) << "\n";
}
}
-
- SmallString<128> Dest;
- path::append(Dest, path::filename(Config->Reproduce), "response.txt");
- maybePrintCpioMember(Dest, Data);
+ return Data.str();
}
std::string elf::findFromSearchPaths(StringRef Path) {
Modified: lld/trunk/ELF/InputFiles.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputFiles.cpp?rev=269593&r1=269592&r2=269593&view=diff
==============================================================================
--- lld/trunk/ELF/InputFiles.cpp (original)
+++ lld/trunk/ELF/InputFiles.cpp Sun May 15 12:10:23 2016
@@ -394,8 +394,9 @@ MemoryBufferRef ArchiveFile::getMember(c
"could not get the buffer for the member defining symbol " +
Sym->getName());
- if (C.getParent()->isThin())
- maybeCopyInputFile(check(C.getFullName()), Ret.getBuffer());
+ if (C.getParent()->isThin() && Driver->Cpio)
+ Driver->Cpio->append(relativeToRoot(check(C.getFullName())),
+ Ret.getBuffer());
return Ret;
}
More information about the llvm-commits
mailing list