From 0b39f055d8879eca308d5c41641f2f47ff0a3925 Mon Sep 17 00:00:00 2001 From: Nico Weber Date: Tue, 1 Jun 2021 06:55:36 -0400 Subject: [PATCH] [lld/mac] Don't write mtimes to N_OSO entries if ZERO_AR_DATE is set. This is important for build determinism. This matches ld64. Differential Revision: https://reviews.llvm.org/D103446 --- lld/MachO/Config.h | 2 ++ lld/MachO/Driver.cpp | 3 +++ lld/MachO/DriverUtils.cpp | 6 ++++++ lld/test/MachO/stabs.s | 38 ++++++++++++++++++++++++++++++++------ 4 files changed, 43 insertions(+), 6 deletions(-) diff --git a/lld/MachO/Config.h b/lld/MachO/Config.h index 471d5da..fba8ba0 100644 --- a/lld/MachO/Config.h +++ b/lld/MachO/Config.h @@ -133,6 +133,8 @@ struct Configuration { SymbolPatterns exportedSymbols; SymbolPatterns unexportedSymbols; + bool zeroModTime = false; + llvm::MachO::Architecture arch() const { return platformInfo.target.Arch; } llvm::MachO::PlatformKind platform() const { diff --git a/lld/MachO/Driver.cpp b/lld/MachO/Driver.cpp index 498924d..9fff29b 100644 --- a/lld/MachO/Driver.cpp +++ b/lld/MachO/Driver.cpp @@ -986,6 +986,9 @@ bool macho::link(ArrayRef argsArr, bool canExitEarly, config->emitFunctionStarts = !args.hasArg(OPT_no_function_starts); config->emitBitcodeBundle = args.hasArg(OPT_bitcode_bundle); + // FIXME: Add a commandline flag for this too. + config->zeroModTime = getenv("ZERO_AR_DATE"); + std::array encryptablePlatforms{ PlatformKind::iOS, PlatformKind::watchOS, PlatformKind::tvOS}; config->emitEncryptionInfo = diff --git a/lld/MachO/DriverUtils.cpp b/lld/MachO/DriverUtils.cpp index d897eef..2c045c5 100644 --- a/lld/MachO/DriverUtils.cpp +++ b/lld/MachO/DriverUtils.cpp @@ -263,6 +263,9 @@ Optional macho::loadArchiveMember(MemoryBufferRef mb, uint32_t modTime, StringRef archiveName, bool objCOnly) { + if (config->zeroModTime) + modTime = 0; + switch (identify_magic(mb.getBuffer())) { case file_magic::macho_object: if (!objCOnly || hasObjCSection(mb)) @@ -280,6 +283,9 @@ Optional macho::loadArchiveMember(MemoryBufferRef mb, } uint32_t macho::getModTime(StringRef path) { + if (config->zeroModTime) + return 0; + fs::file_status stat; if (!fs::status(path, stat)) if (fs::exists(stat)) diff --git a/lld/test/MachO/stabs.s b/lld/test/MachO/stabs.s index c921328..f6c5297 100644 --- a/lld/test/MachO/stabs.s +++ b/lld/test/MachO/stabs.s @@ -11,23 +11,49 @@ # RUN: %lld -lSystem %t/test.o %t/foo.o %t/no-debug.o -o %t/test # RUN: (llvm-objdump --section-headers %t/test; dsymutil -s %t/test) | \ -# RUN: FileCheck %s -DDIR=%t -DFOO_PATH=%t/foo.o +# RUN: FileCheck %s -DDIR=%t -DFOO_PATH=%t/foo.o \ +# RUN: -D#TEST_TIME=0x10 -D#FOO_TIME=0x20 ## Check that we emit the right modtime even when the object file is in an ## archive. # RUN: %lld -lSystem %t/test.o %t/foo.a %t/no-debug.o -o %t/test # RUN: (llvm-objdump --section-headers %t/test; dsymutil -s %t/test) | \ -# RUN: FileCheck %s -DDIR=%t -DFOO_PATH=%t/foo.a\(foo.o\) +# RUN: FileCheck %s -DDIR=%t -DFOO_PATH=%t/foo.a\(foo.o\) \ +# RUN: -D#TEST_TIME=0x10 -D#FOO_TIME=0x20 + +## Check that we don't emit modtimes if ZERO_AR_DATE is set. +# RUN: env ZERO_AR_DATE=1 %lld -lSystem %t/test.o %t/foo.o %t/no-debug.o \ +# RUN: -o %t/test +# RUN: (llvm-objdump --section-headers %t/test; dsymutil -s %t/test) | \ +# RUN: FileCheck %s -DDIR=%t -DFOO_PATH=%t/foo.o \ +# RUN: -D#TEST_TIME=0 -D#FOO_TIME=0 +# RUN: env ZERO_AR_DATE=1 %lld -lSystem %t/test.o %t/foo.a %t/no-debug.o \ +# RUN: -o %t/test +# RUN: (llvm-objdump --section-headers %t/test; dsymutil -s %t/test) | \ +# RUN: FileCheck %s -DDIR=%t -DFOO_PATH=%t/foo.a\(foo.o\) \ +# RUN: -D#TEST_TIME=0 -D#FOO_TIME=0 +# RUN: env ZERO_AR_DATE=1 %lld -lSystem %t/test.o %t/no-debug.o \ +# RUN: -all_load %t/foo.a -o %t/test +# RUN: (llvm-objdump --section-headers %t/test; dsymutil -s %t/test) | \ +# RUN: FileCheck %s -DDIR=%t -DFOO_PATH=%t/foo.a\(foo.o\) \ +# RUN: -D#TEST_TIME=0 -D#FOO_TIME=0 +# RUN: env ZERO_AR_DATE=1 %lld -lSystem %t/test.o %t/no-debug.o \ +# RUN: -force_load %t/foo.a -o %t/test +# RUN: (llvm-objdump --section-headers %t/test; dsymutil -s %t/test) | \ +# RUN: FileCheck %s -DDIR=%t -DFOO_PATH=%t/foo.a\(foo.o\) \ +# RUN: -D#TEST_TIME=0 -D#FOO_TIME=0 ## Check that we emit absolute paths to the object files in our OSO entries ## even if our inputs are relative paths. # RUN: cd %t && %lld -lSystem test.o foo.o no-debug.o -o test # RUN: (llvm-objdump --section-headers %t/test; dsymutil -s %t/test) | \ -# RUN: FileCheck %s -DDIR=%t -DFOO_PATH=%t/foo.o +# RUN: FileCheck %s -DDIR=%t -DFOO_PATH=%t/foo.o \ +# RUN: -D#TEST_TIME=0x10 -D#FOO_TIME=0x20 # RUN: cd %t && %lld -lSystem test.o foo.a no-debug.o -o %t/test # RUN: (llvm-objdump --section-headers %t/test; dsymutil -s %t/test) | \ -# RUN: FileCheck %s -DDIR=%t -DFOO_PATH=%t/foo.a\(foo.o\) +# RUN: FileCheck %s -DDIR=%t -DFOO_PATH=%t/foo.a\(foo.o\) \ +# RUN: -D#TEST_TIME=0x10 -D#FOO_TIME=0x20 # CHECK: Sections: # CHECK-NEXT: Idx Name @@ -38,7 +64,7 @@ # CHECK-NEXT: [[#MORE_TEXT_ID:]] more_text # CHECK: (N_SO ) 00 0000 0000000000000000 '/tmp/test.cpp' -# CHECK-NEXT: (N_OSO ) 03 0001 0000000000000010 '[[DIR]]/test.o' +# CHECK-NEXT: (N_OSO ) 03 0001 [[#%.16x,TEST_TIME]] '[[DIR]]/test.o' # CHECK-NEXT: (N_STSYM ) [[#%.2d,MORE_DATA_ID + 1]] 0000 [[#%.16x,STATIC:]] '_static_var' # CHECK-NEXT: (N_FUN ) [[#%.2d,TEXT_ID + 1]] 0000 [[#%.16x,MAIN:]] '_main' # CHECK-NEXT: (N_FUN ) 00 0000 0000000000000006{{$}} @@ -60,7 +86,7 @@ # CHECK-NEXT: (N_FUN ) 00 0000 0000000000000001{{$}} # CHECK-NEXT: (N_SO ) 01 0000 0000000000000000{{$}} # CHECK-NEXT: (N_SO ) 00 0000 0000000000000000 '/foo.cpp' -# CHECK-NEXT: (N_OSO ) 03 0001 0000000000000020 '[[FOO_PATH]]' +# CHECK-NEXT: (N_OSO ) 03 0001 [[#%.16x,FOO_TIME]] '[[FOO_PATH]]' # CHECK-NEXT: (N_FUN ) [[#%.2d,TEXT_ID + 1]] 0000 [[#%.16x,FOO:]] '_foo' # CHECK-NEXT: (N_FUN ) 00 0000 0000000000000001{{$}} # CHECK-NEXT: (N_SO ) 01 0000 0000000000000000{{$}} -- 2.7.4