diff options
| author | Than McIntosh <thanm@google.com> | 2024-05-20 14:52:57 +0000 |
|---|---|---|
| committer | Than McIntosh <thanm@google.com> | 2024-05-21 18:45:27 +0000 |
| commit | 3bcefa5276c4ec5475df62cfd1fde9315b121d1c (patch) | |
| tree | b26bdd5f6b59110796ef9e77b66042eed3d8cb92 /src/cmd/link/internal/ld/lib.go | |
| parent | f9ba2cff2286d378eca28c841bea8488c69fc30e (diff) | |
| download | go-3bcefa5276c4ec5475df62cfd1fde9315b121d1c.tar.xz | |
cmd/link/internal/ld: rewrite LC_UUID for darwin external links
When building Go binaries using external linking, rewrite the LC_UUID
Macho load command to replace the content placed there by the external
linker, so as to ensure that we get reproducible builds.
Updates #64947.
Change-Id: I263a89d1a067807404febbc801d4dade33bc3288
Reviewed-on: https://go-review.googlesource.com/c/go/+/586079
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
Diffstat (limited to 'src/cmd/link/internal/ld/lib.go')
| -rw-r--r-- | src/cmd/link/internal/ld/lib.go | 55 |
1 files changed, 37 insertions, 18 deletions
diff --git a/src/cmd/link/internal/ld/lib.go b/src/cmd/link/internal/ld/lib.go index 11df3a466d..755c889585 100644 --- a/src/cmd/link/internal/ld/lib.go +++ b/src/cmd/link/internal/ld/lib.go @@ -1356,6 +1356,8 @@ INSERT AFTER .debug_types; return path } +type machoUpdateFunc func(ctxt *Link, exef *os.File, exem *macho.File, outexe string) error + // archive builds a .a archive from the hostobj object files. func (ctxt *Link) archive() { if ctxt.BuildMode != BuildModeCArchive { @@ -1969,6 +1971,30 @@ func (ctxt *Link) hostlink() { ctxt.Logf("%s", out) } + // Helper for updating a Macho binary in some way (shared between + // dwarf combining and UUID update). + updateMachoOutFile := func(op string, updateFunc machoUpdateFunc) { + // For os.Rename to work reliably, must be in same directory as outfile. + rewrittenOutput := *flagOutfile + "~" + exef, err := os.Open(*flagOutfile) + if err != nil { + Exitf("%s: %s failed: %v", os.Args[0], op, err) + } + defer exef.Close() + exem, err := macho.NewFile(exef) + if err != nil { + Exitf("%s: parsing Mach-O header failed: %v", os.Args[0], err) + } + if err := updateFunc(ctxt, exef, exem, rewrittenOutput); err != nil { + Exitf("%s: %s failed: %v", os.Args[0], op, err) + } + os.Remove(*flagOutfile) + if err := os.Rename(rewrittenOutput, *flagOutfile); err != nil { + Exitf("%s: %v", os.Args[0], err) + } + } + + uuidUpdated := false if combineDwarf { // Find "dsymutils" and "strip" tools using CC --print-prog-name. var cc []string @@ -2028,24 +2054,17 @@ func (ctxt *Link) hostlink() { if _, err := os.Stat(dsym); os.IsNotExist(err) { return } - // For os.Rename to work reliably, must be in same directory as outfile. - combinedOutput := *flagOutfile + "~" - exef, err := os.Open(*flagOutfile) - if err != nil { - Exitf("%s: combining dwarf failed: %v", os.Args[0], err) - } - defer exef.Close() - exem, err := macho.NewFile(exef) - if err != nil { - Exitf("%s: parsing Mach-O header failed: %v", os.Args[0], err) - } - if err := machoCombineDwarf(ctxt, exef, exem, dsym, combinedOutput); err != nil { - Exitf("%s: combining dwarf failed: %v", os.Args[0], err) - } - os.Remove(*flagOutfile) - if err := os.Rename(combinedOutput, *flagOutfile); err != nil { - Exitf("%s: %v", os.Args[0], err) - } + updateMachoOutFile("combining dwarf", + func(ctxt *Link, exef *os.File, exem *macho.File, outexe string) error { + return machoCombineDwarf(ctxt, exef, exem, dsym, outexe) + }) + uuidUpdated = true + } + if ctxt.IsDarwin() && !uuidUpdated && *flagBuildid != "" { + updateMachoOutFile("rewriting uuid", + func(ctxt *Link, exef *os.File, exem *macho.File, outexe string) error { + return machoRewriteUuid(ctxt, exef, exem, outexe) + }) } if ctxt.NeedCodeSign() { err := machoCodeSign(ctxt, *flagOutfile) |
