]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/link: add runtime.text.N symbols to macho symbol table in dynlink mode
authorCherry Mui <cherryyz@google.com>
Fri, 17 May 2024 23:59:31 +0000 (19:59 -0400)
committerCherry Mui <cherryyz@google.com>
Mon, 20 May 2024 15:32:53 +0000 (15:32 +0000)
In dynamic linking mode (e.g. when using plugins) on darwin, the
marker symbols runtime.text and runtime.etext are added to Textp
in an early stage, so when adding symbols to the symbol table we
don't need to explicitly add them. However, when splitting text
sections, the runtime.text.N marker symbols for the addtional
sections are not added to Textp. So we do need to add them
explicitly to the symbol table.

Fixes #66993.

Change-Id: Ic718d03cd71fc0bfb931cff82640b1f4c53b89be
Reviewed-on: https://go-review.googlesource.com/c/go/+/586555
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Than McIntosh <thanm@google.com>
src/cmd/cgo/internal/testplugin/plugin_test.go
src/cmd/link/internal/ld/macho.go

index 1e32ff8a066f30204ab425392ba6a2f0b85076c5..4900ada18201567de89e86615f08ce2c2c816618 100644 (file)
@@ -74,6 +74,7 @@ func testMain(m *testing.M) int {
        }
        defer os.RemoveAll(GOPATH)
        tmpDir = GOPATH
+       fmt.Printf("TMPDIR=%s\n", tmpDir)
 
        modRoot := filepath.Join(GOPATH, "src", "testplugin")
        altRoot := filepath.Join(GOPATH, "alt", "src", "testplugin")
@@ -395,3 +396,21 @@ func TestIssue62430(t *testing.T) {
        goCmd(t, "build", "-o", "issue62430.exe", "./issue62430/main.go")
        run(t, "./issue62430.exe")
 }
+
+func TestTextSectionSplit(t *testing.T) {
+       globalSkip(t)
+       if runtime.GOOS != "darwin" || runtime.GOARCH != "arm64" {
+               t.Skipf("text section splitting is not done in %s/%s", runtime.GOOS, runtime.GOARCH)
+       }
+
+       // Use -ldflags=-debugtextsize=262144 to let the linker split text section
+       // at a smaller size threshold, so it actually splits for the test binary.
+       goCmd(nil, "build", "-ldflags=-debugtextsize=262144", "-o", "host-split.exe", "./host")
+       run(t, "./host-split.exe")
+
+       // Check that we did split text sections.
+       syms := goCmd(nil, "tool", "nm", "host-split.exe")
+       if !strings.Contains(syms, "runtime.text.1") {
+               t.Errorf("runtime.text.1 not found, text section not split?")
+       }
+}
index 33d44a3becde7e01a6bf5fe9e46bf987d0632986..34624c25a9f333356fa3eed582a18523bd1317af 100644 (file)
@@ -195,12 +195,12 @@ const (
 )
 
 const (
-       PLATFORM_MACOS          MachoPlatform = 1
-       PLATFORM_IOS            MachoPlatform = 2
-       PLATFORM_TVOS           MachoPlatform = 3
-       PLATFORM_WATCHOS        MachoPlatform = 4
-       PLATFORM_BRIDGEOS       MachoPlatform = 5
-       PLATFORM_MACCATALYST    MachoPlatform = 6
+       PLATFORM_MACOS       MachoPlatform = 1
+       PLATFORM_IOS         MachoPlatform = 2
+       PLATFORM_TVOS        MachoPlatform = 3
+       PLATFORM_WATCHOS     MachoPlatform = 4
+       PLATFORM_BRIDGEOS    MachoPlatform = 5
+       PLATFORM_MACCATALYST MachoPlatform = 6
 )
 
 // rebase table opcode
@@ -900,21 +900,25 @@ func collectmachosyms(ctxt *Link) {
        // Add special runtime.text and runtime.etext symbols (which are local).
        // We've already included this symbol in Textp on darwin if ctxt.DynlinkingGo().
        // See data.go:/textaddress
+       // NOTE: runtime.text.N symbols (if we split text sections) are not added, though,
+       // so we handle them here.
        if !*FlagS {
                if !ctxt.DynlinkingGo() {
                        s := ldr.Lookup("runtime.text", 0)
                        if ldr.SymType(s) == sym.STEXT {
                                addsym(s)
                        }
-                       for n := range Segtext.Sections[1:] {
-                               s := ldr.Lookup(fmt.Sprintf("runtime.text.%d", n+1), 0)
-                               if s != 0 {
-                                       addsym(s)
-                               } else {
-                                       break
-                               }
+               }
+               for n := range Segtext.Sections[1:] {
+                       s := ldr.Lookup(fmt.Sprintf("runtime.text.%d", n+1), 0)
+                       if s != 0 {
+                               addsym(s)
+                       } else {
+                               break
                        }
-                       s = ldr.Lookup("runtime.etext", 0)
+               }
+               if !ctxt.DynlinkingGo() {
+                       s := ldr.Lookup("runtime.etext", 0)
                        if ldr.SymType(s) == sym.STEXT {
                                addsym(s)
                        }