aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/link/internal/ld/lib.go
diff options
context:
space:
mode:
authorThan McIntosh <thanm@google.com>2024-05-20 14:52:57 +0000
committerThan McIntosh <thanm@google.com>2024-05-21 18:45:27 +0000
commit3bcefa5276c4ec5475df62cfd1fde9315b121d1c (patch)
treeb26bdd5f6b59110796ef9e77b66042eed3d8cb92 /src/cmd/link/internal/ld/lib.go
parentf9ba2cff2286d378eca28c841bea8488c69fc30e (diff)
downloadgo-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.go55
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)