[llvm-objcopy] Support --{enable,disable}-deterministic-archives

Summary: ar and objcopy/strip all support configuring whether archives are written deterministically (timestamps/UIDs/GIDs/etc zero'd). This has been ported to llvm-ar (the U/D modifiers) but not yet to llvm-objcopy/strip.

Reviewers: jakehehrlich, jhenderson, alexshap

Reviewed By: jhenderson

Subscribers: ruiu, mgrang, llvm-commits

Differential Revision: https://reviews.llvm.org/D53913

llvm-svn: 345859
This commit is contained in:
Jordan Rupprecht 2018-11-01 17:36:37 +00:00
parent cc1e9c414b
commit fc780bbb16
6 changed files with 110 additions and 4 deletions

View File

@ -0,0 +1,65 @@
# RUN: yaml2obj %s > %t.o
# Create an archive, specifying U so that timestamps/etc. are preserved.
# We only test timestamps as a proxy for full deterministic writing; i.e. we
# assume UID/GIDs are preserved if timestamps are preserved.
# RUN: touch -t 199505050555.55 %t.o
# RUN: rm -f %t.a
# RUN: llvm-ar crsU %t.a %t.o
# Test short flags.
# RUN: llvm-objcopy -D %t.a %t.2D.a
# RUN: env TZ=GMT llvm-ar tv %t.2D.a | FileCheck %s --check-prefix=CHECK-DETERMINISTIC
# RUN: llvm-objcopy -U %t.a %t.2U.a
# RUN: env TZ=GMT llvm-ar tv %t.2U.a | FileCheck %s --check-prefix=CHECK-NONDETERMINISTIC
# RUN: llvm-strip -D %t.a -o %t.3D.a
# RUN: env TZ=GMT llvm-ar tv %t.3D.a | FileCheck %s --check-prefix=CHECK-DETERMINISTIC
# RUN: llvm-strip -U %t.a -o %t.3U.a
# RUN: env TZ=GMT llvm-ar tv %t.3U.a | FileCheck %s --check-prefix=CHECK-NONDETERMINISTIC
# Test long flags.
# RUN: llvm-objcopy --enable-deterministic-archives %t.a %t.4D.a
# RUN: env TZ=GMT llvm-ar tv %t.4D.a | FileCheck %s --check-prefix=CHECK-DETERMINISTIC
# RUN: llvm-objcopy --disable-deterministic-archives %t.a %t.4U.a
# RUN: env TZ=GMT llvm-ar tv %t.4U.a | FileCheck %s --check-prefix=CHECK-NONDETERMINISTIC
# RUN: llvm-strip --enable-deterministic-archives %t.a -o %t.5D.a
# RUN: env TZ=GMT llvm-ar tv %t.5D.a | FileCheck %s --check-prefix=CHECK-DETERMINISTIC
# RUN: llvm-strip --disable-deterministic-archives %t.a -o %t.5U.a
# RUN: env TZ=GMT llvm-ar tv %t.5U.a | FileCheck %s --check-prefix=CHECK-NONDETERMINISTIC
# If unspecified, verify that deterministic is the default.
# RUN: llvm-objcopy %t.a %t.6.a
# RUN: env TZ=GMT llvm-ar tv %t.6.a | FileCheck %s --check-prefix=CHECK-DETERMINISTIC
# RUN: llvm-strip %t.a -o %t.7.a
# RUN: env TZ=GMT llvm-ar tv %t.7.a | FileCheck %s --check-prefix=CHECK-DETERMINISTIC
# If both are specified, last one wins.
# RUN: llvm-objcopy -U -D %t.a %t.8.a
# RUN: env TZ=GMT llvm-ar tv %t.8.a | FileCheck %s --check-prefix=CHECK-DETERMINISTIC
# RUN: llvm-objcopy -D -U %t.a %t.9.a
# RUN: env TZ=GMT llvm-ar tv %t.9.a | FileCheck %s --check-prefix=CHECK-NONDETERMINISTIC
# RUN: llvm-objcopy -D -U -D -U --enable-deterministic-archives %t.a %t.10.a
# RUN: env TZ=GMT llvm-ar tv %t.10.a | FileCheck %s --check-prefix=CHECK-DETERMINISTIC
# RUN: llvm-strip -U -D %t.a -o %t.11.a
# RUN: env TZ=GMT llvm-ar tv %t.11.a | FileCheck %s --check-prefix=CHECK-DETERMINISTIC
# RUN: llvm-strip -D -U %t.a -o %t.12.a
# RUN: env TZ=GMT llvm-ar tv %t.12.a | FileCheck %s --check-prefix=CHECK-NONDETERMINISTIC
# RUN: llvm-strip -D -U -D -U --enable-deterministic-archives %t.a -o %t.13.a
# RUN: env TZ=GMT llvm-ar tv %t.13.a | FileCheck %s --check-prefix=CHECK-DETERMINISTIC
# CHECK-DETERMINISTIC: {{[[:space:]]1970[[:space:]]}}
# CHECK-NONDETERMINISTIC: {{[[:space:]]1995[[:space:]]}}
!ELF
FileHeader:
Class: ELFCLASS64
Data: ELFDATA2LSB
Type: ET_REL
Machine: EM_X86_64
Sections:
- Name: .text
Type: SHT_PROGBITS
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]

View File

@ -343,6 +343,10 @@ DriverConfig parseObjcopyOptions(ArrayRef<const char *> ArgsArr) {
for (auto Arg : InputArgs.filtered(OBJCOPY_keep_symbol))
Config.SymbolsToKeep.push_back(Arg->getValue());
Config.DeterministicArchives = InputArgs.hasFlag(
OBJCOPY_enable_deterministic_archives,
OBJCOPY_disable_deterministic_archives, /*default=*/true);
Config.PreserveDates = InputArgs.hasArg(OBJCOPY_preserve_dates);
if (Config.DecompressDebugSections &&
@ -411,6 +415,10 @@ DriverConfig parseStripOptions(ArrayRef<const char *> ArgsArr) {
for (auto Arg : InputArgs.filtered(STRIP_keep_symbol))
Config.SymbolsToKeep.push_back(Arg->getValue());
Config.DeterministicArchives =
InputArgs.hasFlag(STRIP_enable_deterministic_archives,
STRIP_disable_deterministic_archives, /*default=*/true);
Config.PreserveDates = InputArgs.hasArg(STRIP_preserve_dates);
DriverConfig DC;

View File

@ -72,6 +72,7 @@ struct CopyConfig {
StringMap<StringRef> SymbolsToRename;
// Boolean options
bool DeterministicArchives = true;
bool DiscardAll = false;
bool ExtractDWO = false;
bool KeepFileSymbols = false;

View File

@ -35,6 +35,22 @@ defm split_dwo
"<dwo-file>, then strip-dwo on the input file">,
MetaVarName<"dwo-file">;
def enable_deterministic_archives
: Flag<["-", "--"], "enable-deterministic-archives">,
HelpText<"Enable deterministic mode when copying archives (use zero for "
"UIDs, GIDs, and timestamps).">;
def D : Flag<["-"], "D">,
Alias<enable_deterministic_archives>,
HelpText<"Alias for --enable-deterministic-archives">;
def disable_deterministic_archives
: Flag<["-", "--"], "disable-deterministic-archives">,
HelpText<"Disable deterministic mode when copying archives (use real "
"values for UIDs, GIDs, and timestamps).">;
def U : Flag<["-"], "U">,
Alias<disable_deterministic_archives>,
HelpText<"Alias for --disable-deterministic-archives">;
def preserve_dates : Flag<[ "-", "--" ], "preserve-dates">,
HelpText<"Preserve access and modification timestamps">;

View File

@ -8,6 +8,22 @@ multiclass Eq<string name, string help> {
def help : Flag<["-", "--"], "help">;
def enable_deterministic_archives
: Flag<["-", "--"], "enable-deterministic-archives">,
HelpText<"Enable deterministic mode when stripping archives (use zero "
"for UIDs, GIDs, and timestamps).">;
def D : Flag<["-"], "D">,
Alias<enable_deterministic_archives>,
HelpText<"Alias for --enable-deterministic-archives">;
def disable_deterministic_archives
: Flag<["-", "--"], "disable-deterministic-archives">,
HelpText<"Disable deterministic mode when stripping archives (use real "
"values for UIDs, GIDs, and timestamps).">;
def U : Flag<["-"], "U">,
Alias<disable_deterministic_archives>,
HelpText<"Alias for --disable-deterministic-archives">;
defm output : Eq<"o", "Write output to <file>">,
MetaVarName<"output">;

View File

@ -147,7 +147,7 @@ static void executeObjcopyOnArchive(const CopyConfig &Config,
executeObjcopyOnBinary(Config, *Bin, MB);
Expected<NewArchiveMember> Member =
NewArchiveMember::getOldMember(Child, true);
NewArchiveMember::getOldMember(Child, Config.DeterministicArchives);
if (!Member)
reportError(Ar.getFileName(), Member.takeError());
Member->Buf = MB.releaseMemoryBuffer();
@ -157,9 +157,9 @@ static void executeObjcopyOnArchive(const CopyConfig &Config,
if (Err)
reportError(Config.InputFilename, std::move(Err));
if (Error E =
deepWriteArchive(Config.OutputFilename, NewArchiveMembers,
Ar.hasSymbolTable(), Ar.kind(), true, Ar.isThin()))
if (Error E = deepWriteArchive(Config.OutputFilename, NewArchiveMembers,
Ar.hasSymbolTable(), Ar.kind(),
Config.DeterministicArchives, Ar.isThin()))
reportError(Config.OutputFilename, std::move(E));
}