cmd/link: avoid a copy in Mach-O CodeSign

Mach-O code signing needs to read the content of the output file.
We already have it in a byte slice. Read it without copying.

Change-Id: I6b5670f7b9be076beb51b96ab7772bf93359748a
Reviewed-on: https://go-review.googlesource.com/c/go/+/770681
LUCI-TryBot-Result: golang-scoped@luci-project-accounts.iam.gserviceaccount.com <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: David Chase <drchase@google.com>
This commit is contained in:
Cherry Mui 2026-03-30 10:17:53 -04:00
parent fdd592745d
commit 70e521bdff
2 changed files with 23 additions and 8 deletions

View file

@ -11,6 +11,7 @@
package codesign
import (
"bytes"
"crypto/sha256"
"debug/macho"
"encoding/binary"
@ -247,21 +248,35 @@ func Sign(out []byte, data io.Reader, id string, codeSize, textOff, textSize int
outp = puts(outp, []byte(id+"\000"))
// emit hashes
datab, isBytes := data.(*bytes.Buffer)
var buf [pageSize]byte
p := 0
for p < int(codeSize) {
n, err := io.ReadFull(data, buf[:])
if err == io.EOF {
break
}
if err != nil && err != io.ErrUnexpectedEOF {
panic(err)
var chunk []byte
if isBytes {
// If it is already a byte slice, we can read without copying
chunk = datab.Next(pageSize)
if len(chunk) == 0 {
break
}
} else {
n, err := io.ReadFull(data, buf[:])
if err == io.EOF {
break
}
if err != nil && err != io.ErrUnexpectedEOF {
panic(err)
}
chunk = buf[:n]
}
n := len(chunk)
if p+n > int(codeSize) {
n = int(codeSize) - p
chunk = chunk[:n]
}
p += n
b := sha256.Sum256(buf[:n])
b := sha256.Sum256(chunk)
outp = puts(outp, b[:])
}
}

View file

@ -880,7 +880,7 @@ func asmbMacho(ctxt *Link) {
if int64(len(data)) != codesigOff {
panic("wrong size")
}
codesign.Sign(ldr.Data(cs), bytes.NewReader(data), "a.out", codesigOff, int64(mstext.fileoffset), int64(mstext.filesize), ctxt.IsExe() || ctxt.IsPIE())
codesign.Sign(ldr.Data(cs), bytes.NewBuffer(data), "a.out", codesigOff, int64(mstext.fileoffset), int64(mstext.filesize), ctxt.IsExe() || ctxt.IsPIE())
ctxt.Out.SeekSet(codesigOff)
ctxt.Out.Write(ldr.Data(cs))
}