]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/link: add runtime.text.N symbols to Mach-O symbol table
authorCherry Mui <cherryyz@google.com>
Wed, 29 Sep 2021 20:47:12 +0000 (16:47 -0400)
committerCherry Mui <cherryyz@google.com>
Thu, 30 Sep 2021 16:43:32 +0000 (16:43 +0000)
On Darwin/ARM64 when external linking, for very large text we
split it into multiple sections. For each section (other than the
first) we create runtime.text.N marker symbols. In CL 316050 I
forgot to add those symbols to the symbol table. This CL does it.

It doesn't actually matter for program execution. But we add them
on ELF when splitting text sections, so we do it here as well.
Also, this makes it easier to tell if we split text sections.

Change-Id: Ida7f8e9431867881e5ee2bc1a2129eeaf83cb878
Reviewed-on: https://go-review.googlesource.com/c/go/+/353209
Trust: Cherry Mui <cherryyz@google.com>
Run-TryBot: Cherry Mui <cherryyz@google.com>
Reviewed-by: Than McIntosh <thanm@google.com>
src/cmd/link/internal/ld/ld_test.go
src/cmd/link/internal/ld/macho.go

index 3702a4d08f586f3674da2f083cbdc493a939586c..2d5a7add9d22d146660763eacf891d31151c4c3e 100644 (file)
@@ -5,6 +5,7 @@
 package ld
 
 import (
+       "bytes"
        "debug/pe"
        "fmt"
        "internal/testenv"
@@ -154,13 +155,22 @@ func TestLargeTextSectionSplitting(t *testing.T) {
        // is arbitrary; we just need something sufficiently large that uses
        // external linking.
        exe := filepath.Join(dir, "go.exe")
-       out, eerr := exec.Command(testenv.GoToolPath(t), "build", "-o", exe, "-ldflags=-linkmode=external -debugtextsize=1048576", "cmd/go").CombinedOutput()
-       if eerr != nil {
-               t.Fatalf("build failure: %s\n%s\n", eerr, string(out))
+       out, err := exec.Command(testenv.GoToolPath(t), "build", "-o", exe, "-ldflags=-linkmode=external -debugtextsize=1048576", "cmd/go").CombinedOutput()
+       if err != nil {
+               t.Fatalf("build failure: %s\n%s\n", err, string(out))
+       }
+
+       // Check that we did split text sections.
+       out, err = exec.Command(testenv.GoToolPath(t), "tool", "nm", exe).CombinedOutput()
+       if err != nil {
+               t.Fatalf("nm failure: %s\n%s\n", err, string(out))
+       }
+       if !bytes.Contains(out, []byte("runtime.text.1")) {
+               t.Errorf("runtime.text.1 not found, text section not split?")
        }
 
        // Result should be runnable.
-       _, err := exec.Command(exe, "version").CombinedOutput()
+       _, err = exec.Command(exe, "version").CombinedOutput()
        if err != nil {
                t.Fatal(err)
        }
index a577a5308d59ff8d4aea83077b08bbc49865a92d..8633222ee332fbd9cb717a49acff6af2c15bb2cf 100644 (file)
@@ -897,6 +897,14 @@ func collectmachosyms(ctxt *Link) {
                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
+                       }
+               }
                s = ldr.Lookup("runtime.etext", 0)
                if ldr.SymType(s) == sym.STEXT {
                        addsym(s)