Skip to content

Commit

Permalink
Add support for deterministically linked binaries on macOS to lldb.
Browse files Browse the repository at this point in the history
When ld64 links a binary deterministically using the flag ZERO_AR_DATE,
it sets a timestamp of 0 for N_OSO members in the symtab section, rather
than the usual last modified date of the object file. Prior to this
patch, lldb would compare the timestamp from the N_OSO member against
the last modified date of the object file, and skip loading the object
file if there was a mismatch. This patch updates the logic to ignore the
timestamp check if the N_OSO member has timestamp 0.

The original logic was added in https://reviews.llvm.org/rL181631 as a
safety check to avoid problems when debugging if the object file was out
of date. This was prior to the introduction of deterministic build in
ld64. lld still doesn't support deterministic build.

Other code in llvm already relies on and uses the assumption that a
timestamp of 0 means deterministic build. For example, commit
9ccfddc adds similar timestamp checking
logic to dsymutil, but special cases timestamp 0. Likewise, commit
0d1bb79 adds a long comment describing
deterministic archive, which mostly uses timestamp 0 for determinism.

Patch from Erik Chen <erikchen@chromium.org>!

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

llvm-svn: 368199
  • Loading branch information
nico committed Aug 7, 2019
1 parent 353938e commit 8883ec7
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 1 deletion.
11 changes: 11 additions & 0 deletions lldb/lit/SymbolFile/DWARF/deterministic-build.cpp
@@ -0,0 +1,11 @@
// Test that binaries linked deterministically (N_OSO has timestamp 0) can still
// have their object files loaded by lldb. Note that the env var ZERO_AR_DATE
// requires the ld64 linker, which clang invokes by default.
// REQUIRES: system-darwin
// RUN: %clang %s -g -c -o %t.o
// RUN: ZERO_AR_DATE=1 %clang %t.o -g -o %t
// RUN: %lldb %t -o "breakpoint set -f %s -l 11" -o run -o exit | FileCheck %s
// CHECK: stop reason = breakpoint


int main() { return 0; }
Expand Up @@ -420,7 +420,11 @@ Module *SymbolFileDWARFDebugMap::GetModuleByCompUnitInfo(
// than the one from the CU.
auto oso_mod_time = std::chrono::time_point_cast<std::chrono::seconds>(
FileSystem::Instance().GetModificationTime(oso_file));
if (oso_mod_time != comp_unit_info->oso_mod_time) {
// A timestamp of 0 means that the linker was in deterministic mode. In
// that case, we should skip the check against the filesystem last
// modification timestamp, since it will never match.
if (comp_unit_info->oso_mod_time != llvm::sys::TimePoint<>() &&
oso_mod_time != comp_unit_info->oso_mod_time) {
obj_file->GetModule()->ReportError(
"debug map object file '%s' has changed (actual time is "
"%s, debug map time is %s"
Expand Down

0 comments on commit 8883ec7

Please sign in to comment.