[lld] r332613 - [COFF] Add /Brepro and /TIMESTAMP options.
Zachary Turner via llvm-commits
llvm-commits at lists.llvm.org
Thu May 17 08:11:01 PDT 2018
Author: zturner
Date: Thu May 17 08:11:01 2018
New Revision: 332613
URL: http://llvm.org/viewvc/llvm-project?rev=332613&view=rev
Log:
[COFF] Add /Brepro and /TIMESTAMP options.
Previously we would always write a hash of the binary into the
PE file, for reproducible builds. This breaks AppCompat, which
is a feature of Windows that relies on the timestamp in the PE
header being set to a real value (or at the very least, a value
that satisfies certain properties).
To address this, we put the old behavior of writing the hash
behind the /Brepro flag, which mimics MSVC linker behavior. We
also match MSVC default behavior, which is to write an actual
timestamp to the PE header. Finally, we add the /TIMESTAMP
option (an lld extension) so that the user can specify the exact
value to be used in case he/she manually constructs a value which
is both reproducible and satisfies AppCompat.
Differential Revision: https://reviews.llvm.org/D46966
Added:
lld/trunk/test/COFF/timestamp.test
Modified:
lld/trunk/COFF/Config.h
lld/trunk/COFF/Driver.cpp
lld/trunk/COFF/Options.td
lld/trunk/COFF/Writer.cpp
Modified: lld/trunk/COFF/Config.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Config.h?rev=332613&r1=332612&r2=332613&view=diff
==============================================================================
--- lld/trunk/COFF/Config.h (original)
+++ lld/trunk/COFF/Config.h Thu May 17 08:11:01 2018
@@ -181,6 +181,7 @@ struct Configuration {
uint32_t MinorImageVersion = 0;
uint32_t MajorOSVersion = 6;
uint32_t MinorOSVersion = 0;
+ uint32_t Timestamp = 0;
bool DynamicBase = true;
bool AllowBind = true;
bool NxCompat = true;
@@ -194,6 +195,7 @@ struct Configuration {
bool WarnLocallyDefinedImported = true;
bool Incremental = true;
bool KillAt = false;
+ bool Repro = false;
};
extern Configuration *Config;
Modified: lld/trunk/COFF/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Driver.cpp?rev=332613&r1=332612&r2=332613&view=diff
==============================================================================
--- lld/trunk/COFF/Driver.cpp (original)
+++ lld/trunk/COFF/Driver.cpp Thu May 17 08:11:01 2018
@@ -1033,6 +1033,23 @@ void LinkerDriver::link(ArrayRef<const c
parseSubsystem(Arg->getValue(), &Config->Subsystem, &Config->MajorOSVersion,
&Config->MinorOSVersion);
+ // Handle /timestamp
+ if (llvm::opt::Arg *Arg = Args.getLastArg(OPT_timestamp, OPT_repro)) {
+ if (Arg->getOption().getID() == OPT_repro) {
+ Config->Timestamp = 0;
+ Config->Repro = true;
+ } else {
+ Config->Repro = false;
+ StringRef Value(Arg->getValue());
+ if (Value.getAsInteger(0, Config->Timestamp))
+ fatal(Twine("invalid timestamp: ") + Value +
+ ". Expected 32-bit integer");
+ }
+ } else {
+ Config->Repro = false;
+ Config->Timestamp = time(nullptr);
+ }
+
// Handle /alternatename
for (auto *Arg : Args.filtered(OPT_alternatename))
parseAlternateName(Arg->getValue());
Modified: lld/trunk/COFF/Options.td
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Options.td?rev=332613&r1=332612&r2=332613&view=diff
==============================================================================
--- lld/trunk/COFF/Options.td (original)
+++ lld/trunk/COFF/Options.td Thu May 17 08:11:01 2018
@@ -58,6 +58,7 @@ def section : P<"section", "Specify sect
def stack : P<"stack", "Size of the stack">;
def stub : P<"stub", "Specify DOS stub file">;
def subsystem : P<"subsystem", "Specify subsystem">;
+def timestamp : P<"timestamp", "Specify the PE header timestamp">;
def version : P<"version", "Specify a version number in the PE header">;
def wholearchive_file : P<"wholearchive", "Include all object files from this archive">;
@@ -89,6 +90,7 @@ def driver : P<"driver", "Generate a Win
def nodefaultlib_all : F<"nodefaultlib">;
def noentry : F<"noentry">;
def profile : F<"profile">;
+def repro : F<"Brepro">, HelpText<"Use a hash of the executable as the PE header timestamp">;
def swaprun_cd : F<"swaprun:cd">;
def swaprun_net : F<"swaprun:net">;
def verbose : F<"verbose">;
Modified: lld/trunk/COFF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Writer.cpp?rev=332613&r1=332612&r2=332613&view=diff
==============================================================================
--- lld/trunk/COFF/Writer.cpp (original)
+++ lld/trunk/COFF/Writer.cpp Thu May 17 08:11:01 2018
@@ -1192,16 +1192,18 @@ void Writer::writeBuildId() {
reinterpret_cast<const char *>(Buffer->getBufferStart()),
Buffer->getBufferSize());
- uint32_t Hash = static_cast<uint32_t>(xxHash64(OutputFileData));
+ uint32_t Timestamp = Config->Timestamp;
+ if (Config->Repro)
+ Timestamp = static_cast<uint32_t>(xxHash64(OutputFileData));
if (DebugDirectory)
- DebugDirectory->setTimeDateStamp(Hash);
+ DebugDirectory->setTimeDateStamp(Timestamp);
uint8_t *Buf = Buffer->getBufferStart();
Buf += DOSStubSize + sizeof(PEMagic);
object::coff_file_header *CoffHeader =
reinterpret_cast<coff_file_header *>(Buf);
- CoffHeader->TimeDateStamp = Hash;
+ CoffHeader->TimeDateStamp = Timestamp;
}
// Sort .pdata section contents according to PE/COFF spec 5.5.
Added: lld/trunk/test/COFF/timestamp.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/COFF/timestamp.test?rev=332613&view=auto
==============================================================================
--- lld/trunk/test/COFF/timestamp.test (added)
+++ lld/trunk/test/COFF/timestamp.test Thu May 17 08:11:01 2018
@@ -0,0 +1,18 @@
+rm %t.*.exe
+RUN: yaml2obj %p/Inputs/generic.yaml > %t.obj
+RUN: lld-link %t.obj /debug /Brepro /entry:main /nodefaultlib /out:%t.1.exe
+RUN: lld-link %t.obj /debug /Brepro /entry:main /nodefaultlib /out:%t.2.exe
+RUN: lld-link %t.obj /debug /timestamp:0 /entry:main /nodefaultlib /out:%t.3.exe
+RUN: llvm-readobj -file-headers -coff-debug-directory %t.1.exe | FileCheck %s --check-prefix=HASH
+RUN: llvm-readobj -file-headers -coff-debug-directory %t.2.exe | FileCheck %s --check-prefix=HASH
+RUN: llvm-readobj -file-headers -coff-debug-directory %t.3.exe | FileCheck %s --check-prefix=ZERO
+
+HASH: ImageFileHeader {
+HASH: TimeDateStamp: [[STAMP:.*]]
+HASH: DebugDirectory [
+HASH: TimeDateStamp: [[STAMP]]
+
+ZERO: ImageFileHeader {
+ZERO: TimeDateStamp: 1970-01-01 00:00:00 (0x0)
+ZERO: DebugDirectory [
+ZERO: TimeDateStamp: 1970-01-01 00:00:00 (0x0)
More information about the llvm-commits
mailing list