cmd/link: don't mangle string symbol names

String symbol names could contain weird characters as we put the
string literal into the symbol name. So it may appear to need
mangling. However, as string symbols are grouped into a single
"go:string.*" symbol, the individual symbol names actually don't
matter. So don't mangle them.

Also make the mangling code more defensive in case of weird
symbol names.

Fixes #62098.

Change-Id: I533012567a9fffab69debda934f426421c7abb04
Reviewed-on: https://go-review.googlesource.com/c/go/+/520856
Reviewed-by: Than McIntosh <thanm@google.com>
Run-TryBot: Cherry Mui <cherryyz@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
This commit is contained in:
Cherry Mui 2023-08-18 11:10:23 -04:00
parent d63c88d695
commit b65e34f038
3 changed files with 31 additions and 8 deletions

View File

@ -380,9 +380,11 @@ func TestForkExec(t *testing.T) {
}
}
func TestGeneric(t *testing.T) {
func TestSymbolNameMangle(t *testing.T) {
// Issue 58800: generic function name may contain weird characters
// that confuse the external linker.
// Issue 62098: the name mangling code doesn't handle some string
// symbols correctly.
globalSkip(t)
goCmd(t, "build", "-buildmode=plugin", "-o", "generic.so", "./generic/plugin.go")
goCmd(t, "build", "-buildmode=plugin", "-o", "mangle.so", "./mangle/plugin.go")
}

View File

@ -2,21 +2,37 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Instantiated function name may contain weird characters
// that confuse the external linker, so it needs to be
// mangled.
// Test cases for symbol name mangling.
package main
//go:noinline
func F[T any]() {}
import (
"fmt"
"strings"
)
// Issue 58800:
// Instantiated function name may contain weird characters
// that confuse the external linker, so it needs to be
// mangled.
type S struct {
X int `parser:"|@@)"`
}
//go:noinline
func F[T any]() {}
func P() {
F[S]()
}
// Issue 62098: the name mangling code doesn't handle some string
// symbols correctly.
func G(id string) error {
if strings.ContainsAny(id, "&$@;/:+,?\\{^}%`]\">[~<#|") {
return fmt.Errorf("invalid")
}
return nil
}
func main() {}

View File

@ -993,6 +993,11 @@ func typeSymbolMangle(name string) string {
if strings.HasPrefix(name, "type:runtime.") {
return name
}
if strings.HasPrefix(name, "go:string.") {
// String symbols will be grouped to a single go:string.* symbol.
// No need to mangle individual symbol names.
return name
}
if len(name) <= 14 && !strings.Contains(name, "@") { // Issue 19529
return name
}
@ -1007,7 +1012,7 @@ func typeSymbolMangle(name string) string {
// instantiated symbol, replace type name in []
i := strings.IndexByte(name, '[')
j := strings.LastIndexByte(name, ']')
if j == -1 {
if j == -1 || j <= i {
j = len(name)
}
hash := notsha256.Sum256([]byte(name[i+1 : j]))