cmd/link: add runtime.text.N symbols to macho symbol table in dynlink mode

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>
This commit is contained in:
Cherry Mui 2024-05-17 19:59:31 -04:00
parent e3d87d1932
commit 9a9dd72d5c
2 changed files with 37 additions and 14 deletions

View 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?")
}
}

View 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)
}