Skip to content

Conversation

@kubkon
Copy link
Member

@kubkon kubkon commented Jun 19, 2023

This PR effectively undos the following found in #13964:

MachO now generates a fully reproducible UUID value between runs. It matches the behaviour of Apple's ld64 in that calculating the UUID for a binary, we exclude regions in the final binary that are non-deterministic, i.e. depend on the presence of debug info stabs in the file, and these include:

  • __LINKEDIT segment command header
  • LC_SYMTAB and LC_DYSYMTAB command headers
  • LC_CODE_SIGNATURE command header
  • subsection of the actual symbol table containing the debug info symbol stabs
  • subsection of the actual string table containing the strings of the debug info symbol stabs
  • code signature

This means we can now fully parallelize UUID calculation for MachO binaries at the expense of full compatibility with ld64. This also means we are in-sync with LLVM's MachO LLD driver.

This also implies that the following is no longer the case:

$ zig cc -shared testlib.c -o testlib.dylib -O2 -g
$ cp testlib.dylib testlib_g.dylib
$ zig cc -shared testlib.c -o testlib.dylib -O2 -s

$ otool -l testlib.dylib | grep uuid
    uuid D780AB99-65F8-30C7-AC8A-BE1001DE24C4

$ otool -l testlib_g.dylib | grep uuid
    uuid D780AB99-65F8-30C7-AC8A-BE1001DE24C4

Since we now don't exclude debug info stabs from UUID calculation, the UUID values will differ for output binaries with and without debug info. If anyone relies on this feature, I would encourage you to let me know in the comments of this PR so that we can judge if it is a feature we should keep or is expendable. The main downside of status quo (and Apple's approach) is the fact that it is slow to evaluate, and while for small projects the difference will be negligible, for larger ones it will make a noticeable impact as shown below (./zld refers to the linker with the patch applied, while ./zld_old is the status quo):

> hyperfine ./zld ./zld_old
Benchmark 1: ./zld
  Time (mean ± σ):      2.182 s ±  0.007 s    [User: 2.353 s, System: 0.749 s]
  Range (min … max):    2.171 s …  2.197 s    10 runs

Benchmark 2: ./zld_old
  Time (mean ± σ):      2.691 s ±  0.015 s    [User: 2.260 s, System: 0.748 s]
  Range (min … max):    2.670 s …  2.722 s    10 runs

Summary
  './zld' ran
    1.23 ± 0.01 times faster than './zld_old'

Finally, since we no longer aim at fully matching ld64's behaviour, we can now close #14964.

@kubkon kubkon added this to the 0.11.0 milestone Jun 19, 2023
@kubkon kubkon merged commit 7b5bd3a into master Jun 20, 2023
@kubkon kubkon deleted the macho-faster-uuid branch June 20, 2023 22:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

port uuid link test over to the new build system API

1 participant