forked from OSchip/llvm-project
[llvm-strip] Add support for -p/--preserve-dates
Summary: [llvm-strip] Preserve access/modification timestamps when -p is used. Reviewers: jakehehrlich, jhenderson, alexshap Reviewed By: jhenderson Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D50744 llvm-svn: 339921
This commit is contained in:
parent
8b5e6991d2
commit
d1767dc56f
|
@ -0,0 +1,70 @@
|
|||
# Note: ls -lu prints the accessed timestamp, ls -l prints the modified timestamp
|
||||
|
||||
# Preserve dates when stripping to an output file.
|
||||
# RUN: yaml2obj %s > %t.1.o
|
||||
# RUN: touch -a -t 199505050555.55 %t.1.o
|
||||
# RUN: touch -m -t 199705050555.55 %t.1.o
|
||||
# RUN: llvm-strip -p %t.1.o -o %t-preserved.1.o
|
||||
# RUN: ls -lu %t-preserved.1.o | FileCheck %s --check-prefix=CHECK-PRESERVE-ATIME
|
||||
# RUN: ls -l %t-preserved.1.o | FileCheck %s --check-prefix=CHECK-PRESERVE-MTIME
|
||||
|
||||
# Preserve dates available via objcopy interface as well.
|
||||
# RUN: yaml2obj %s > %t.2.o
|
||||
# RUN: touch -a -t 199505050555.55 %t.2.o
|
||||
# RUN: touch -m -t 199705050555.55 %t.2.o
|
||||
# RUN: llvm-objcopy -p %t.2.o %t-preserved.2.o
|
||||
# RUN: ls -lu %t-preserved.2.o | FileCheck %s --check-prefix=CHECK-PRESERVE-ATIME
|
||||
# RUN: ls -l %t-preserved.2.o | FileCheck %s --check-prefix=CHECK-PRESERVE-MTIME
|
||||
|
||||
# Preserve dates when stripping in place.
|
||||
# RUN: yaml2obj %s > %t.3.o
|
||||
# RUN: touch -a -t 199505050555.55 %t.3.o
|
||||
# RUN: touch -m -t 199705050555.55 %t.3.o
|
||||
# RUN: llvm-strip -p %t.3.o
|
||||
# RUN: ls -lu %t.3.o | FileCheck %s --check-prefix=CHECK-PRESERVE-ATIME
|
||||
# RUN: ls -l %t.3.o | FileCheck %s --check-prefix=CHECK-PRESERVE-MTIME
|
||||
|
||||
# Without -p set, don't preserve dates.
|
||||
# RUN: yaml2obj %s > %t.4.o
|
||||
# RUN: touch -a -t 199505050555.55 %t.4.o
|
||||
# RUN: touch -m -t 199705050555.55 %t.4.o
|
||||
# RUN: llvm-strip %t.4.o
|
||||
# RUN: ls -lu %t.4.o | FileCheck %s --check-prefix=CHECK-NO-PRESERVE-ATIME
|
||||
# RUN: ls -l %t.4.o | FileCheck %s --check-prefix=CHECK-NO-PRESERVE-MTIME
|
||||
|
||||
# Preserve dates in archives.
|
||||
# RUN: yaml2obj %s > %t.5.o
|
||||
# RUN: rm -f %t.a
|
||||
# RUN: llvm-ar cr %t.a %t.5.o
|
||||
# RUN: touch -a -t 199505050555.55 %t.a
|
||||
# RUN: touch -m -t 199705050555.55 %t.a
|
||||
# RUN: llvm-strip -p %t.a
|
||||
# RUN: ls -lu %t.a | FileCheck %s --check-prefix=CHECK-PRESERVE-ATIME
|
||||
# RUN: ls -l %t.a | FileCheck %s --check-prefix=CHECK-PRESERVE-MTIME
|
||||
|
||||
# Preserve dates in split DWO files.
|
||||
# RUN: cp %p/Inputs/dwarf.dwo %t-input.dwo
|
||||
# RUN: touch -a -t 199505050555.55 %t-input.dwo
|
||||
# RUN: touch -m -t 199705050555.55 %t-input.dwo
|
||||
# RUN: llvm-objcopy -p -split-dwo=%t-dwo %t-input.dwo %t-nondwo
|
||||
# RUN: ls -lu %t-dwo | FileCheck %s --check-prefix=CHECK-PRESERVE-ATIME
|
||||
# RUN: ls -l %t-dwo | FileCheck %s --check-prefix=CHECK-PRESERVE-MTIME
|
||||
# RUN: ls -lu %t-nondwo | FileCheck %s --check-prefix=CHECK-PRESERVE-ATIME
|
||||
# RUN: ls -l %t-nondwo | FileCheck %s --check-prefix=CHECK-PRESERVE-MTIME
|
||||
|
||||
# CHECK-PRESERVE-ATIME: 1995
|
||||
# CHECK-PRESERVE-MTIME: 1997
|
||||
|
||||
# CHECK-NO-PRESERVE-ATIME-NOT: 1995
|
||||
# CHECK-NO-PRESERVE-MTIME-NOT: 1997
|
||||
|
||||
!ELF
|
||||
FileHeader:
|
||||
Class: ELFCLASS64
|
||||
Data: ELFDATA2LSB
|
||||
Type: ET_REL
|
||||
Machine: EM_X86_64
|
||||
Sections:
|
||||
- Name: .text
|
||||
Type: SHT_PROGBITS
|
||||
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
|
|
@ -22,6 +22,12 @@ def O : JoinedOrSeparate<["-"], "O">,
|
|||
defm split_dwo : Eq<"split-dwo">,
|
||||
MetaVarName<"dwo-file">,
|
||||
HelpText<"Equivalent to extract-dwo on the input file to <dwo-file>, then strip-dwo on the input file">;
|
||||
|
||||
def preserve_dates : Flag<[ "-", "--" ], "preserve-dates">,
|
||||
HelpText<"Preserve access and modification timestamps">;
|
||||
|
||||
def p : Flag<[ "-" ], "p">, Alias<preserve_dates>;
|
||||
|
||||
defm add_gnu_debuglink : Eq<"add-gnu-debuglink">,
|
||||
MetaVarName<"debug-file">,
|
||||
HelpText<"Add a .gnu_debuglink for <debug-file>">;
|
||||
|
|
|
@ -11,6 +11,11 @@ defm output : Eq<"o">,
|
|||
MetaVarName<"output">,
|
||||
HelpText<"Write output to <file>">;
|
||||
|
||||
def preserve_dates : Flag<[ "-", "--" ], "preserve-dates">,
|
||||
HelpText<"Preserve access and modification timestamps">;
|
||||
|
||||
def p : Flag<[ "-" ], "p">, Alias<preserve_dates>;
|
||||
|
||||
def strip_all : Flag<["-", "--"], "strip-all">,
|
||||
HelpText<"Remove non-allocated sections other than .gnu.warning* sections">;
|
||||
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#include "llvm/Support/FileOutputBuffer.h"
|
||||
#include "llvm/Support/InitLLVM.h"
|
||||
#include "llvm/Support/Path.h"
|
||||
#include "llvm/Support/Process.h"
|
||||
#include "llvm/Support/WithColor.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include <algorithm>
|
||||
|
@ -161,6 +162,7 @@ struct CopyConfig {
|
|||
bool DiscardAll = false;
|
||||
bool OnlyKeepDebug = false;
|
||||
bool KeepFileSymbols = false;
|
||||
bool PreserveDates = false;
|
||||
};
|
||||
|
||||
using SectionPred = std::function<bool(const SectionBase &Sec)>;
|
||||
|
@ -675,17 +677,44 @@ static void executeElfObjcopyOnArchive(const CopyConfig &Config,
|
|||
reportError(Config.OutputFilename, std::move(E));
|
||||
}
|
||||
|
||||
static void restoreDateOnFile(StringRef Filename,
|
||||
const sys::fs::file_status &Stat) {
|
||||
int FD;
|
||||
|
||||
if (auto EC = sys::fs::openFileForWrite(Filename, FD))
|
||||
reportError(Filename, EC);
|
||||
|
||||
if (auto EC = sys::fs::setLastAccessAndModificationTime(
|
||||
FD, Stat.getLastAccessedTime(), Stat.getLastModificationTime()))
|
||||
reportError(Filename, EC);
|
||||
|
||||
if (auto EC = sys::Process::SafelyCloseFileDescriptor(FD))
|
||||
reportError(Filename, EC);
|
||||
}
|
||||
|
||||
static void executeElfObjcopy(const CopyConfig &Config) {
|
||||
sys::fs::file_status Stat;
|
||||
if (Config.PreserveDates)
|
||||
if (auto EC = sys::fs::status(Config.InputFilename, Stat))
|
||||
reportError(Config.InputFilename, EC);
|
||||
|
||||
Expected<OwningBinary<llvm::object::Binary>> BinaryOrErr =
|
||||
createBinary(Config.InputFilename);
|
||||
if (!BinaryOrErr)
|
||||
reportError(Config.InputFilename, BinaryOrErr.takeError());
|
||||
|
||||
if (Archive *Ar = dyn_cast<Archive>(BinaryOrErr.get().getBinary()))
|
||||
return executeElfObjcopyOnArchive(Config, *Ar);
|
||||
if (Archive *Ar = dyn_cast<Archive>(BinaryOrErr.get().getBinary())) {
|
||||
executeElfObjcopyOnArchive(Config, *Ar);
|
||||
} else {
|
||||
FileBuffer FB(Config.OutputFilename);
|
||||
executeElfObjcopyOnBinary(Config, *BinaryOrErr.get().getBinary(), FB);
|
||||
}
|
||||
|
||||
FileBuffer FB(Config.OutputFilename);
|
||||
executeElfObjcopyOnBinary(Config, *BinaryOrErr.get().getBinary(), FB);
|
||||
if (Config.PreserveDates) {
|
||||
restoreDateOnFile(Config.OutputFilename, Stat);
|
||||
if (!Config.SplitDWO.empty())
|
||||
restoreDateOnFile(Config.SplitDWO, Stat);
|
||||
}
|
||||
}
|
||||
|
||||
// ParseObjcopyOptions returns the config and sets the input arguments. If a
|
||||
|
@ -780,6 +809,8 @@ static CopyConfig parseObjcopyOptions(ArrayRef<const char *> ArgsArr) {
|
|||
for (auto Arg : InputArgs.filtered(OBJCOPY_keep_symbol))
|
||||
Config.SymbolsToKeep.push_back(Arg->getValue());
|
||||
|
||||
Config.PreserveDates = InputArgs.hasArg(OBJCOPY_preserve_dates);
|
||||
|
||||
return Config;
|
||||
}
|
||||
|
||||
|
@ -834,6 +865,8 @@ static CopyConfig parseStripOptions(ArrayRef<const char *> ArgsArr) {
|
|||
for (auto Arg : InputArgs.filtered(STRIP_keep_symbol))
|
||||
Config.SymbolsToKeep.push_back(Arg->getValue());
|
||||
|
||||
Config.PreserveDates = InputArgs.hasArg(STRIP_preserve_dates);
|
||||
|
||||
return Config;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue