diff --git a/lld/MachO/Config.h b/lld/MachO/Config.h --- a/lld/MachO/Config.h +++ b/lld/MachO/Config.h @@ -133,6 +133,8 @@ 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 --- a/lld/MachO/Driver.cpp +++ b/lld/MachO/Driver.cpp @@ -986,6 +986,9 @@ 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 --- a/lld/MachO/DriverUtils.cpp +++ b/lld/MachO/DriverUtils.cpp @@ -263,6 +263,9 @@ 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 @@ } 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 --- 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{{$}}