cmd/link: emit LC_BUILD_VERSION on Mach-O

LC_VERSION_MIN_MACOSX seems deprecated. Emit LC_BUILD_VERSION
instead. Also emit it on darwin/arm64, where it was not emitted
before.

Fixes #45091.

Change-Id: I18fb80d571f681da3bd258e53beb520e68f354bd
Reviewed-on: https://go-review.googlesource.com/c/go/+/312550
Trust: Cherry Zhang <cherryyz@google.com>
Run-TryBot: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Than McIntosh <thanm@google.com>
This commit is contained in:
Cherry Zhang 2021-04-21 19:12:38 -04:00
parent b2a032add8
commit d5b2d809b0
2 changed files with 21 additions and 25 deletions

View file

@ -472,24 +472,20 @@ func (ctxt *Link) domacho() {
if buildcfg.GOOS == "ios" { if buildcfg.GOOS == "ios" {
machoPlatform = PLATFORM_IOS machoPlatform = PLATFORM_IOS
} }
switch ctxt.Arch.Family { if ctxt.LinkMode == LinkInternal && machoPlatform == PLATFORM_MACOS {
default: var version uint32
if ctxt.LinkMode == LinkInternal { switch ctxt.Arch.Family {
// For lldb, must say LC_VERSION_MIN_MACOSX or else case sys.AMD64:
// it won't know that this Mach-O binary is from OS X
// (could be iOS or WatchOS instead).
// Go on iOS uses linkmode=external, and linkmode=external
// adds this itself. So we only need this code for linkmode=internal
// and we can assume OS X.
//
// See golang.org/issues/12941.
//
// The version must be at least 10.9; see golang.org/issues/30488. // The version must be at least 10.9; see golang.org/issues/30488.
ml := newMachoLoad(ctxt.Arch, LC_VERSION_MIN_MACOSX, 2) version = 10<<16 | 9<<8 | 0<<0 // 10.9.0
ml.data[0] = 10<<16 | 9<<8 | 0<<0 // OS X version 10.9.0 case sys.ARM64:
ml.data[1] = 10<<16 | 9<<8 | 0<<0 // SDK 10.9.0 version = 11<<16 | 0<<8 | 0<<0 // 11.0.0
} }
case sys.ARM64: ml := newMachoLoad(ctxt.Arch, LC_BUILD_VERSION, 4)
ml.data[0] = uint32(machoPlatform)
ml.data[1] = version // OS version
ml.data[2] = version // SDK version
ml.data[3] = 0 // ntools
} }
} }

View file

@ -333,12 +333,12 @@ func TestXFlag(t *testing.T) {
} }
} }
var testMacOSVersionSrc = ` var testMachOBuildVersionSrc = `
package main package main
func main() { } func main() { }
` `
func TestMacOSVersion(t *testing.T) { func TestMachOBuildVersion(t *testing.T) {
testenv.MustHaveGoBuild(t) testenv.MustHaveGoBuild(t)
t.Parallel() t.Parallel()
@ -346,7 +346,7 @@ func TestMacOSVersion(t *testing.T) {
tmpdir := t.TempDir() tmpdir := t.TempDir()
src := filepath.Join(tmpdir, "main.go") src := filepath.Join(tmpdir, "main.go")
err := ioutil.WriteFile(src, []byte(testMacOSVersionSrc), 0666) err := ioutil.WriteFile(src, []byte(testMachOBuildVersionSrc), 0666)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -371,28 +371,28 @@ func TestMacOSVersion(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
found := false found := false
const LC_VERSION_MIN_MACOSX = 0x24 const LC_BUILD_VERSION = 0x32
checkMin := func(ver uint32) { checkMin := func(ver uint32) {
major, minor := (ver>>16)&0xff, (ver>>8)&0xff major, minor := (ver>>16)&0xff, (ver>>8)&0xff
if major != 10 || minor < 9 { if major != 10 || minor < 9 {
t.Errorf("LC_VERSION_MIN_MACOSX version %d.%d < 10.9", major, minor) t.Errorf("LC_BUILD_VERSION version %d.%d < 10.9", major, minor)
} }
} }
for _, cmd := range exem.Loads { for _, cmd := range exem.Loads {
raw := cmd.Raw() raw := cmd.Raw()
type_ := exem.ByteOrder.Uint32(raw) type_ := exem.ByteOrder.Uint32(raw)
if type_ != LC_VERSION_MIN_MACOSX { if type_ != LC_BUILD_VERSION {
continue continue
} }
osVer := exem.ByteOrder.Uint32(raw[8:]) osVer := exem.ByteOrder.Uint32(raw[12:])
checkMin(osVer) checkMin(osVer)
sdkVer := exem.ByteOrder.Uint32(raw[12:]) sdkVer := exem.ByteOrder.Uint32(raw[16:])
checkMin(sdkVer) checkMin(sdkVer)
found = true found = true
break break
} }
if !found { if !found {
t.Errorf("no LC_VERSION_MIN_MACOSX load command found") t.Errorf("no LC_BUILD_VERSION load command found")
} }
} }