From 397654d66a4f84d4439e046cd330d9968af3b62b Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Fri, 2 Oct 2020 16:03:37 -0700 Subject: cmd/go, cmd/cgo: update gofrontend mangling checks This is a port of two patches in the master repository. https://golang.org/cl/259298 cmd/cgo: split gofrontend mangling checks into cmd/internal/pkgpath This is a step toward porting https://golang.org/cl/219817 from the gofrontend repo to the main repo. Note that this also corrects the implementation of the v2 mangling scheme to use ..u and ..U where appropriate. https://golang.org/cl/259299 cmd/go: use cmd/internal/pkgpath for gccgo pkgpath symbol For golang/go#37272 For golang/go#41862 Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/270637 --- libgo/go/cmd/cgo/main.go | 3 +- libgo/go/cmd/cgo/out.go | 118 ++++--------------------- libgo/go/cmd/go/internal/work/gccgo.go | 47 +++++----- libgo/go/cmd/internal/pkgpath/pkgpath.go | 114 ++++++++++++++++++++++++ libgo/go/cmd/internal/pkgpath/pkgpath_test.go | 121 ++++++++++++++++++++++++++ 5 files changed, 273 insertions(+), 130 deletions(-) create mode 100644 libgo/go/cmd/internal/pkgpath/pkgpath.go create mode 100644 libgo/go/cmd/internal/pkgpath/pkgpath_test.go (limited to 'libgo/go') diff --git a/libgo/go/cmd/cgo/main.go b/libgo/go/cmd/cgo/main.go index 7fc2508..4952118 100644 --- a/libgo/go/cmd/cgo/main.go +++ b/libgo/go/cmd/cgo/main.go @@ -244,8 +244,7 @@ var exportHeader = flag.String("exportheader", "", "where to write export header var gccgo = flag.Bool("gccgo", false, "generate files for use with gccgo") var gccgoprefix = flag.String("gccgoprefix", "", "-fgo-prefix option used with gccgo") var gccgopkgpath = flag.String("gccgopkgpath", "", "-fgo-pkgpath option used with gccgo") -var gccgoMangleCheckDone bool -var gccgoNewmanglingInEffect bool +var gccgoMangler func(string) string var importRuntimeCgo = flag.Bool("import_runtime_cgo", true, "import runtime/cgo in generated code") var importSyscall = flag.Bool("import_syscall", true, "import syscall in generated code") var goarch, goos string diff --git a/libgo/go/cmd/cgo/out.go b/libgo/go/cmd/cgo/out.go index dd03f7d..2ab8425 100644 --- a/libgo/go/cmd/cgo/out.go +++ b/libgo/go/cmd/cgo/out.go @@ -6,6 +6,7 @@ package main import ( "bytes" + "cmd/internal/pkgpath" "debug/elf" "debug/macho" "debug/pe" @@ -15,7 +16,6 @@ import ( "go/token" "internal/xcoff" "io" - "io/ioutil" "os" "os/exec" "path/filepath" @@ -1286,112 +1286,24 @@ func (p *Package) writeExportHeader(fgcch io.Writer) { fmt.Fprintf(fgcch, "%s\n", p.gccExportHeaderProlog()) } -// gccgoUsesNewMangling reports whether gccgo uses the new collision-free -// packagepath mangling scheme (see determineGccgoManglingScheme for more -// info). -func gccgoUsesNewMangling() bool { - if !gccgoMangleCheckDone { - gccgoNewmanglingInEffect = determineGccgoManglingScheme() - gccgoMangleCheckDone = true - } - return gccgoNewmanglingInEffect -} - -const mangleCheckCode = ` -package läufer -func Run(x int) int { - return 1 -} -` - -// determineGccgoManglingScheme performs a runtime test to see which -// flavor of packagepath mangling gccgo is using. Older versions of -// gccgo use a simple mangling scheme where there can be collisions -// between packages whose paths are different but mangle to the same -// string. More recent versions of gccgo use a new mangler that avoids -// these collisions. Return value is whether gccgo uses the new mangling. -func determineGccgoManglingScheme() bool { - - // Emit a small Go file for gccgo to compile. - filepat := "*_gccgo_manglecheck.go" - var f *os.File - var err error - if f, err = ioutil.TempFile(*objDir, filepat); err != nil { - fatalf("%v", err) - } - gofilename := f.Name() - defer os.Remove(gofilename) - - if err = ioutil.WriteFile(gofilename, []byte(mangleCheckCode), 0666); err != nil { - fatalf("%v", err) - } - - // Compile with gccgo, capturing generated assembly. - gccgocmd := os.Getenv("GCCGO") - if gccgocmd == "" { - gpath, gerr := exec.LookPath("gccgo") - if gerr != nil { - fatalf("unable to locate gccgo: %v", gerr) - } - gccgocmd = gpath - } - cmd := exec.Command(gccgocmd, "-S", "-o", "-", gofilename) - buf, cerr := cmd.CombinedOutput() - if cerr != nil { - fatalf("%s", cerr) - } - - // New mangling: expect go.l..u00e4ufer.Run - // Old mangling: expect go.l__ufer.Run - return regexp.MustCompile(`go\.l\.\.u00e4ufer\.Run`).Match(buf) -} - -// gccgoPkgpathToSymbolNew converts a package path to a gccgo-style -// package symbol. -func gccgoPkgpathToSymbolNew(ppath string) string { - bsl := []byte{} - changed := false - for _, c := range []byte(ppath) { - switch { - case 'A' <= c && c <= 'Z', 'a' <= c && c <= 'z', - '0' <= c && c <= '9', c == '_': - bsl = append(bsl, c) - case c == '.': - bsl = append(bsl, ".x2e"...) - default: - changed = true - encbytes := []byte(fmt.Sprintf("..z%02x", c)) - bsl = append(bsl, encbytes...) - } - } - if !changed { - return ppath - } - return string(bsl) -} - -// gccgoPkgpathToSymbolOld converts a package path to a gccgo-style -// package symbol using the older mangling scheme. -func gccgoPkgpathToSymbolOld(ppath string) string { - clean := func(r rune) rune { - switch { - case 'A' <= r && r <= 'Z', 'a' <= r && r <= 'z', - '0' <= r && r <= '9': - return r - } - return '_' - } - return strings.Map(clean, ppath) -} - // gccgoPkgpathToSymbol converts a package path to a mangled packagepath // symbol. func gccgoPkgpathToSymbol(ppath string) string { - if gccgoUsesNewMangling() { - return gccgoPkgpathToSymbolNew(ppath) - } else { - return gccgoPkgpathToSymbolOld(ppath) + if gccgoMangler == nil { + var err error + cmd := os.Getenv("GCCGO") + if cmd == "" { + cmd, err = exec.LookPath("gccgo") + if err != nil { + fatalf("unable to locate gccgo: %v", err) + } + } + gccgoMangler, err = pkgpath.ToSymbolFunc(cmd, *objDir) + if err != nil { + fatalf("%v", err) + } } + return gccgoMangler(ppath) } // Return the package prefix when using gccgo. diff --git a/libgo/go/cmd/go/internal/work/gccgo.go b/libgo/go/cmd/go/internal/work/gccgo.go index 63d5c62..dbaff70 100644 --- a/libgo/go/cmd/go/internal/work/gccgo.go +++ b/libgo/go/cmd/go/internal/work/gccgo.go @@ -11,11 +11,13 @@ import ( "os/exec" "path/filepath" "strings" + "sync" "cmd/go/internal/base" "cmd/go/internal/cfg" "cmd/go/internal/load" "cmd/go/internal/str" + "cmd/internal/pkgpath" ) // The Gccgo toolchain. @@ -174,7 +176,7 @@ func (tools gccgoToolchain) asm(b *Builder, a *Action, sfiles []string) ([]strin ofiles = append(ofiles, ofile) sfile = mkAbs(p.Dir, sfile) defs := []string{"-D", "GOOS_" + cfg.Goos, "-D", "GOARCH_" + cfg.Goarch} - if pkgpath := gccgoCleanPkgpath(p); pkgpath != "" { + if pkgpath := tools.gccgoCleanPkgpath(b, p); pkgpath != "" { defs = append(defs, `-D`, `GOPKGPATH=`+pkgpath) } defs = tools.maybePIC(defs) @@ -556,7 +558,7 @@ func (tools gccgoToolchain) cc(b *Builder, a *Action, ofile, cfile string) error cfile = mkAbs(p.Dir, cfile) defs := []string{"-D", "GOOS_" + cfg.Goos, "-D", "GOARCH_" + cfg.Goarch} defs = append(defs, b.gccArchArgs()...) - if pkgpath := gccgoCleanPkgpath(p); pkgpath != "" { + if pkgpath := tools.gccgoCleanPkgpath(b, p); pkgpath != "" { defs = append(defs, `-D`, `GOPKGPATH="`+pkgpath+`"`) } compiler := envList("CC", cfg.DefaultCC(cfg.Goos, cfg.Goarch)) @@ -596,28 +598,23 @@ func gccgoPkgpath(p *load.Package) string { return p.ImportPath } -// gccgoCleanPkgpath returns the form of p's pkgpath that gccgo uses -// for symbol names. This is like gccgoPkgpathToSymbolNew in cmd/cgo/out.go. -func gccgoCleanPkgpath(p *load.Package) string { - ppath := gccgoPkgpath(p) - bsl := []byte{} - changed := false - for _, c := range []byte(ppath) { - switch { - case 'A' <= c && c <= 'Z', 'a' <= c && c <= 'z', - '0' <= c && c <= '9', c == '_': - bsl = append(bsl, c) - case c == '.': - bsl = append(bsl, ".x2e"...) - changed = true - default: - encbytes := []byte(fmt.Sprintf("..z%02x", c)) - bsl = append(bsl, encbytes...) - changed = true +var gccgoToSymbolFuncOnce sync.Once +var gccgoToSymbolFunc func(string) string + +func (tools gccgoToolchain) gccgoCleanPkgpath(b *Builder, p *load.Package) string { + gccgoToSymbolFuncOnce.Do(func() { + if cfg.BuildN { + gccgoToSymbolFunc = func(s string) string { return s } + return } - } - if !changed { - return ppath - } - return string(bsl) + fn, err := pkgpath.ToSymbolFunc(tools.compiler(), b.WorkDir) + if err != nil { + fmt.Fprintf(os.Stderr, "cmd/go: %v\n", err) + base.SetExitStatus(2) + base.Exit() + } + gccgoToSymbolFunc = fn + }) + + return gccgoToSymbolFunc(gccgoPkgpath(p)) } diff --git a/libgo/go/cmd/internal/pkgpath/pkgpath.go b/libgo/go/cmd/internal/pkgpath/pkgpath.go new file mode 100644 index 0000000..0b24468 --- /dev/null +++ b/libgo/go/cmd/internal/pkgpath/pkgpath.go @@ -0,0 +1,114 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package pkgpath determines the package path used by gccgo/GoLLVM symbols. +// This package is not used for the gc compiler. +package pkgpath + +import ( + "bytes" + "errors" + "fmt" + "io/ioutil" + "os" + "os/exec" + "strings" +) + +// ToSymbolFunc returns a function that may be used to convert a +// package path into a string suitable for use as a symbol. +// cmd is the gccgo/GoLLVM compiler in use, and tmpdir is a temporary +// directory to pass to ioutil.TempFile. +// For example, this returns a function that converts "net/http" +// into a string like "net..z2fhttp". The actual string varies for +// different gccgo/GoLLVM versions, which is why this returns a function +// that does the conversion appropriate for the compiler in use. +func ToSymbolFunc(cmd, tmpdir string) (func(string) string, error) { + // To determine the scheme used by cmd, we compile a small + // file and examine the assembly code. Older versions of gccgo + // use a simple mangling scheme where there can be collisions + // between packages whose paths are different but mangle to + // the same string. More recent versions use a new mangler + // that avoids these collisions. + const filepat = "*_gccgo_manglechck.go" + f, err := ioutil.TempFile(tmpdir, filepat) + if err != nil { + return nil, err + } + gofilename := f.Name() + f.Close() + defer os.Remove(gofilename) + + if err := ioutil.WriteFile(gofilename, []byte(mangleCheckCode), 0644); err != nil { + return nil, err + } + + command := exec.Command(cmd, "-S", "-o", "-", gofilename) + buf, err := command.Output() + if err != nil { + return nil, err + } + + // New mangling: expect go.l..u00e4ufer.Run + // Old mangling: expect go.l__ufer.Run + if bytes.Contains(buf, []byte("go.l..u00e4ufer.Run")) { + return toSymbolV2, nil + } else if bytes.Contains(buf, []byte("go.l__ufer.Run")) { + return toSymbolV1, nil + } else { + return nil, errors.New(cmd + ": unrecognized mangling scheme") + } +} + +// mangleCheckCode is the package we compile to determine the mangling scheme. +const mangleCheckCode = ` +package läufer +func Run(x int) int { + return 1 +} +` + +// toSymbolV1 converts a package path using the original mangling scheme. +func toSymbolV1(ppath string) string { + clean := func(r rune) rune { + switch { + case 'A' <= r && r <= 'Z', 'a' <= r && r <= 'z', + '0' <= r && r <= '9': + return r + } + return '_' + } + return strings.Map(clean, ppath) +} + +// toSymbolV2 converts a package path using the newer mangling scheme. +func toSymbolV2(ppath string) string { + // This has to build at boostrap time, so it has to build + // with Go 1.4, so we don't use strings.Builder. + bsl := make([]byte, 0, len(ppath)) + changed := false + for _, c := range ppath { + if ('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z') || ('0' <= c && c <= '9') || c == '_' { + bsl = append(bsl, byte(c)) + continue + } + var enc string + switch { + case c == '.': + enc = ".x2e" + case c < 0x80: + enc = fmt.Sprintf("..z%02x", c) + case c < 0x10000: + enc = fmt.Sprintf("..u%04x", c) + default: + enc = fmt.Sprintf("..U%08x", c) + } + bsl = append(bsl, enc...) + changed = true + } + if !changed { + return ppath + } + return string(bsl) +} diff --git a/libgo/go/cmd/internal/pkgpath/pkgpath_test.go b/libgo/go/cmd/internal/pkgpath/pkgpath_test.go new file mode 100644 index 0000000..7355f81 --- /dev/null +++ b/libgo/go/cmd/internal/pkgpath/pkgpath_test.go @@ -0,0 +1,121 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package pkgpath + +import ( + "os" + "testing" +) + +const testEnvName = "GO_PKGPATH_TEST_COMPILER" + +// This init function supports TestToSymbolFunc. For simplicity, +// we use the test binary itself as a sample gccgo driver. +// We set an environment variable to specify how it should behave. +func init() { + switch os.Getenv(testEnvName) { + case "": + return + case "v1": + os.Stdout.WriteString(`.string "go.l__ufer.Run"`) + os.Exit(0) + case "v2": + os.Stdout.WriteString(`.string "go.l..u00e4ufer.Run"`) + os.Exit(0) + case "error": + os.Stdout.WriteString(`unknown string`) + os.Exit(0) + } +} + +func TestToSymbolFunc(t *testing.T) { + const input = "pä世🜃" + tests := []struct { + env string + fail bool + mangled string + }{ + { + env: "v1", + mangled: "p___", + }, + { + env: "v2", + mangled: "p..u00e4..u4e16..U0001f703", + }, + { + env: "error", + fail: true, + }, + } + + cmd := os.Args[0] + tmpdir := t.TempDir() + + defer os.Unsetenv(testEnvName) + + for _, test := range tests { + t.Run(test.env, func(t *testing.T) { + os.Setenv(testEnvName, test.env) + + fn, err := ToSymbolFunc(cmd, tmpdir) + if err != nil { + if !test.fail { + t.Errorf("ToSymbolFunc(%q, %q): unexpected error %v", cmd, tmpdir, err) + } + } else if test.fail { + t.Errorf("ToSymbolFunc(%q, %q) succeeded but expected to fail", cmd, tmpdir) + } else if got, want := fn(input), test.mangled; got != want { + t.Errorf("ToSymbolFunc(%q, %q)(%q) = %q, want %q", cmd, tmpdir, input, got, want) + } + }) + } +} + +var symbolTests = []struct { + input, v1, v2 string +}{ + { + "", + "", + "", + }, + { + "bytes", + "bytes", + "bytes", + }, + { + "net/http", + "net_http", + "net..z2fhttp", + }, + { + "golang.org/x/net/http", + "golang_org_x_net_http", + "golang.x2eorg..z2fx..z2fnet..z2fhttp", + }, + { + "pä世.🜃", + "p____", + "p..u00e4..u4e16.x2e..U0001f703", + }, +} + +func TestV1(t *testing.T) { + for _, test := range symbolTests { + if got, want := toSymbolV1(test.input), test.v1; got != want { + t.Errorf("toSymbolV1(%q) = %q, want %q", test.input, got, want) + } + } +} + +func TestV2(t *testing.T) { + for _, test := range symbolTests { + if got, want := toSymbolV2(test.input), test.v2; got != want { + t.Errorf("toSymbolV2(%q) = %q, want %q", test.input, got, want) + } + } +} -- cgit v1.1 From a01dda3c23b836754814fab1cab949a1bbc641e8 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Mon, 16 Nov 2020 20:06:53 -0800 Subject: compiler, libgo: change mangling scheme Overhaul the mangling scheme to avoid ambiguities if the package path contains a dot. Instead of using dot both to separate components and to mangle characters, use dot only to separate components and use underscore to mangle characters. For golang/go#41862 Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/271726 --- libgo/go/cmd/cgo/out.go | 23 ++++--- libgo/go/cmd/internal/pkgpath/pkgpath.go | 68 +++++++++++++++++-- libgo/go/cmd/internal/pkgpath/pkgpath_test.go | 22 ++++++- libgo/go/go/internal/srcimporter/srcimporter.go | 2 +- libgo/go/internal/bytealg/bytealg.c | 10 +-- libgo/go/internal/cpu/cpu_gccgo.c | 20 +++--- libgo/go/log/syslog/syslog_c.c | 2 +- libgo/go/runtime/atomic_pointer.go | 12 ++-- libgo/go/runtime/chan.go | 2 +- libgo/go/runtime/cpuprof.go | 4 +- libgo/go/runtime/debug.go | 2 +- libgo/go/runtime/heapdump.go | 2 +- libgo/go/runtime/iface.go | 2 +- libgo/go/runtime/internal/atomic/atomic.c | 56 ++++++++-------- libgo/go/runtime/malloc.go | 6 +- libgo/go/runtime/map.go | 2 +- libgo/go/runtime/mbarrier.go | 2 +- libgo/go/runtime/mgc.go | 4 +- libgo/go/runtime/mheap.go | 2 +- libgo/go/runtime/mprof.go | 2 +- libgo/go/runtime/mstats.go | 2 +- libgo/go/runtime/net_plan9.go | 4 +- libgo/go/runtime/netpoll.go | 18 ++--- libgo/go/runtime/pprof/mprof_test.go | 20 +++--- libgo/go/runtime/pprof/pprof_test.go | 4 +- libgo/go/runtime/preempt.go | 2 +- libgo/go/runtime/proc.go | 26 ++++---- libgo/go/runtime/proflabel.go | 4 +- libgo/go/runtime/rdebug.go | 4 +- libgo/go/runtime/runtime.go | 4 +- libgo/go/runtime/runtime1.go | 2 +- libgo/go/runtime/sema.go | 22 +++---- libgo/go/runtime/sigqueue.go | 12 ++-- libgo/go/runtime/symtab.go | 88 ++++++++++++++++--------- libgo/go/runtime/trace.go | 8 +-- libgo/go/runtime/traceback_gccgo.go | 4 +- libgo/go/sync/atomic/atomic.c | 52 +++++++-------- 37 files changed, 315 insertions(+), 206 deletions(-) (limited to 'libgo/go') diff --git a/libgo/go/cmd/cgo/out.go b/libgo/go/cmd/cgo/out.go index 2ab8425..0544139 100644 --- a/libgo/go/cmd/cgo/out.go +++ b/libgo/go/cmd/cgo/out.go @@ -191,7 +191,7 @@ func (p *Package) writeDefs() { panic(fmt.Errorf("invalid var kind %q", n.Kind)) } if *gccgo { - fmt.Fprintf(fc, `extern void *%s __asm__("%s.%s");`, n.Mangle, gccgoSymbolPrefix, n.Mangle) + fmt.Fprintf(fc, `extern void *%s __asm__("%s.%s");`, n.Mangle, gccgoSymbolPrefix, gccgoToSymbol(n.Mangle)) fmt.Fprintf(&gccgoInit, "\t%s = &%s;\n", n.Mangle, n.C) fmt.Fprintf(fc, "\n") } @@ -1168,7 +1168,7 @@ func (p *Package) writeGccgoExports(fgo2, fm, fgcc, fgcch io.Writer) { // will not be able to link against it from the C // code. goName := "Cgoexp_" + exp.ExpName - fmt.Fprintf(fgcc, `extern %s %s %s __asm__("%s.%s");`, cRet, goName, cParams, gccgoSymbolPrefix, goName) + fmt.Fprintf(fgcc, `extern %s %s %s __asm__("%s.%s");`, cRet, goName, cParams, gccgoSymbolPrefix, gccgoToSymbol(goName)) fmt.Fprint(fgcc, "\n") fmt.Fprint(fgcc, "\nCGO_NO_SANITIZE_THREAD\n") @@ -1202,7 +1202,7 @@ func (p *Package) writeGccgoExports(fgo2, fm, fgcc, fgcch io.Writer) { fmt.Fprint(fgcc, "}\n") // Dummy declaration for _cgo_main.c - fmt.Fprintf(fm, `char %s[1] __asm__("%s.%s");`, goName, gccgoSymbolPrefix, goName) + fmt.Fprintf(fm, `char %s[1] __asm__("%s.%s");`, goName, gccgoSymbolPrefix, gccgoToSymbol(goName)) fmt.Fprint(fm, "\n") // For gccgo we use a wrapper function in Go, in order @@ -1286,9 +1286,8 @@ func (p *Package) writeExportHeader(fgcch io.Writer) { fmt.Fprintf(fgcch, "%s\n", p.gccExportHeaderProlog()) } -// gccgoPkgpathToSymbol converts a package path to a mangled packagepath -// symbol. -func gccgoPkgpathToSymbol(ppath string) string { +// gccgoToSymbol converts a name to a mangled symbol for gccgo. +func gccgoToSymbol(ppath string) string { if gccgoMangler == nil { var err error cmd := os.Getenv("GCCGO") @@ -1313,12 +1312,12 @@ func (p *Package) gccgoSymbolPrefix() string { } if *gccgopkgpath != "" { - return gccgoPkgpathToSymbol(*gccgopkgpath) + return gccgoToSymbol(*gccgopkgpath) } if *gccgoprefix == "" && p.PackageName == "main" { return "main" } - prefix := gccgoPkgpathToSymbol(*gccgoprefix) + prefix := gccgoToSymbol(*gccgoprefix) if prefix == "" { prefix = "go" } @@ -1710,8 +1709,12 @@ void _cgoPREFIX_Cfunc__Cmalloc(void *v) { ` func (p *Package) cPrologGccgo() string { - return strings.Replace(strings.Replace(cPrologGccgo, "PREFIX", cPrefix, -1), - "GCCGOSYMBOLPREF", p.gccgoSymbolPrefix(), -1) + r := strings.NewReplacer( + "PREFIX", cPrefix, + "GCCGOSYMBOLPREF", p.gccgoSymbolPrefix(), + "_cgoCheckPointer", gccgoToSymbol("_cgoCheckPointer"), + "_cgoCheckResult", gccgoToSymbol("_cgoCheckResult")) + return r.Replace(cPrologGccgo) } const cPrologGccgo = ` diff --git a/libgo/go/cmd/internal/pkgpath/pkgpath.go b/libgo/go/cmd/internal/pkgpath/pkgpath.go index 0b24468..40a040a 100644 --- a/libgo/go/cmd/internal/pkgpath/pkgpath.go +++ b/libgo/go/cmd/internal/pkgpath/pkgpath.go @@ -50,9 +50,12 @@ func ToSymbolFunc(cmd, tmpdir string) (func(string) string, error) { return nil, err } - // New mangling: expect go.l..u00e4ufer.Run - // Old mangling: expect go.l__ufer.Run - if bytes.Contains(buf, []byte("go.l..u00e4ufer.Run")) { + // Original mangling: go.l__ufer.Run + // Mangling v2: go.l..u00e4ufer.Run + // Mangling v3: go_0l_u00e4ufer.Run + if bytes.Contains(buf, []byte("go_0l_u00e4ufer.Run")) { + return toSymbolV3, nil + } else if bytes.Contains(buf, []byte("go.l..u00e4ufer.Run")) { return toSymbolV2, nil } else if bytes.Contains(buf, []byte("go.l__ufer.Run")) { return toSymbolV1, nil @@ -82,7 +85,7 @@ func toSymbolV1(ppath string) string { return strings.Map(clean, ppath) } -// toSymbolV2 converts a package path using the newer mangling scheme. +// toSymbolV2 converts a package path using the second mangling scheme. func toSymbolV2(ppath string) string { // This has to build at boostrap time, so it has to build // with Go 1.4, so we don't use strings.Builder. @@ -112,3 +115,60 @@ func toSymbolV2(ppath string) string { } return string(bsl) } + +// v3UnderscoreCodes maps from a character that supports an underscore +// encoding to the underscore encoding character. +var v3UnderscoreCodes = map[byte]byte{ + '_': '_', + '.': '0', + '/': '1', + '*': '2', + ',': '3', + '{': '4', + '}': '5', + '[': '6', + ']': '7', + '(': '8', + ')': '9', + '"': 'a', + ' ': 'b', + ';': 'c', +} + +// toSymbolV3 converts a package path using the third mangling scheme. +func toSymbolV3(ppath string) string { + // This has to build at boostrap time, so it has to build + // with Go 1.4, so we don't use strings.Builder. + bsl := make([]byte, 0, len(ppath)) + changed := false + for _, c := range ppath { + if ('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z') || ('0' <= c && c <= '9') { + bsl = append(bsl, byte(c)) + continue + } + + if c < 0x80 { + if u, ok := v3UnderscoreCodes[byte(c)]; ok { + bsl = append(bsl, '_', u) + changed = true + continue + } + } + + var enc string + switch { + case c < 0x80: + enc = fmt.Sprintf("_x%02x", c) + case c < 0x10000: + enc = fmt.Sprintf("_u%04x", c) + default: + enc = fmt.Sprintf("_U%08x", c) + } + bsl = append(bsl, enc...) + changed = true + } + if !changed { + return ppath + } + return string(bsl) +} diff --git a/libgo/go/cmd/internal/pkgpath/pkgpath_test.go b/libgo/go/cmd/internal/pkgpath/pkgpath_test.go index 7355f81..232e803 100644 --- a/libgo/go/cmd/internal/pkgpath/pkgpath_test.go +++ b/libgo/go/cmd/internal/pkgpath/pkgpath_test.go @@ -24,6 +24,9 @@ func init() { case "v2": os.Stdout.WriteString(`.string "go.l..u00e4ufer.Run"`) os.Exit(0) + case "v3": + os.Stdout.WriteString(`.string "go_0l_u00e4ufer.Run"`) + os.Exit(0) case "error": os.Stdout.WriteString(`unknown string`) os.Exit(0) @@ -46,6 +49,10 @@ func TestToSymbolFunc(t *testing.T) { mangled: "p..u00e4..u4e16..U0001f703", }, { + env: "v3", + mangled: "p_u00e4_u4e16_U0001f703", + }, + { env: "error", fail: true, }, @@ -75,32 +82,37 @@ func TestToSymbolFunc(t *testing.T) { } var symbolTests = []struct { - input, v1, v2 string + input, v1, v2, v3 string }{ { "", "", "", + "", }, { "bytes", "bytes", "bytes", + "bytes", }, { "net/http", "net_http", "net..z2fhttp", + "net_1http", }, { "golang.org/x/net/http", "golang_org_x_net_http", "golang.x2eorg..z2fx..z2fnet..z2fhttp", + "golang_0org_1x_1net_1http", }, { "pä世.🜃", "p____", "p..u00e4..u4e16.x2e..U0001f703", + "p_u00e4_u4e16_0_U0001f703", }, } @@ -119,3 +131,11 @@ func TestV2(t *testing.T) { } } } + +func TestV3(t *testing.T) { + for _, test := range symbolTests { + if got, want := toSymbolV3(test.input), test.v3; got != want { + t.Errorf("toSymbolV3(%q) = %q, want %q", test.input, got, want) + } + } +} diff --git a/libgo/go/go/internal/srcimporter/srcimporter.go b/libgo/go/go/internal/srcimporter/srcimporter.go index 90bb3a9..3a2ca9a 100644 --- a/libgo/go/go/internal/srcimporter/srcimporter.go +++ b/libgo/go/go/internal/srcimporter/srcimporter.go @@ -262,5 +262,5 @@ func (p *Importer) joinPath(elem ...string) string { return filepath.Join(elem...) } -//go:linkname setUsesCgo go/types.srcimporter_setUsesCgo +//go:linkname setUsesCgo go_1types.srcimporter__setUsesCgo func setUsesCgo(conf *types.Config) diff --git a/libgo/go/internal/bytealg/bytealg.c b/libgo/go/internal/bytealg/bytealg.c index 969732d..6c08340 100644 --- a/libgo/go/internal/bytealg/bytealg.c +++ b/libgo/go/internal/bytealg/bytealg.c @@ -38,7 +38,7 @@ static const void *goMemmem(const void *in, size_t inl, const void *s, size_t sl #endif intgo Compare(struct __go_open_array, struct __go_open_array) - __asm__(GOSYM_PREFIX "internal..z2fbytealg.Compare") + __asm__(GOSYM_PREFIX "internal_1bytealg.Compare") __attribute__((no_split_stack)); intgo Compare(struct __go_open_array a, struct __go_open_array b) @@ -69,7 +69,7 @@ intgo Compare(struct __go_open_array a, struct __go_open_array b) } intgo IndexByte(struct __go_open_array, byte) - __asm__(GOSYM_PREFIX "internal..z2fbytealg.IndexByte") + __asm__(GOSYM_PREFIX "internal_1bytealg.IndexByte") __attribute__((no_split_stack)); intgo IndexByte(struct __go_open_array b, byte c) @@ -85,7 +85,7 @@ intgo IndexByte(struct __go_open_array b, byte c) intgo IndexByteString(String, byte) - __asm__(GOSYM_PREFIX "internal..z2fbytealg.IndexByteString") + __asm__(GOSYM_PREFIX "internal_1bytealg.IndexByteString") __attribute__((no_split_stack)); intgo IndexByteString(String s, byte c) @@ -100,7 +100,7 @@ intgo IndexByteString(String s, byte c) } intgo Index(struct __go_open_array, struct __go_open_array) - __asm__(GOSYM_PREFIX "internal..z2fbytealg.Index") + __asm__(GOSYM_PREFIX "internal_1bytealg.Index") __attribute__((no_split_stack)); intgo Index(struct __go_open_array a, struct __go_open_array b) @@ -115,7 +115,7 @@ intgo Index(struct __go_open_array a, struct __go_open_array b) } intgo IndexString(String, String) - __asm__(GOSYM_PREFIX "internal..z2fbytealg.IndexString") + __asm__(GOSYM_PREFIX "internal_1bytealg.IndexString") __attribute__((no_split_stack)); intgo IndexString(String a, String b) diff --git a/libgo/go/internal/cpu/cpu_gccgo.c b/libgo/go/internal/cpu/cpu_gccgo.c index 6b40f01..da26f4d 100644 --- a/libgo/go/internal/cpu/cpu_gccgo.c +++ b/libgo/go/internal/cpu/cpu_gccgo.c @@ -21,7 +21,7 @@ struct cpuid_ret { }; struct cpuid_ret cpuid(uint32_t, uint32_t) - __asm__(GOSYM_PREFIX "internal..z2fcpu.cpuid") + __asm__(GOSYM_PREFIX "internal_1cpu.cpuid") __attribute__((no_split_stack)); struct cpuid_ret cpuid(uint32_t eaxArg, uint32_t ecxArg) { @@ -45,7 +45,7 @@ struct xgetbv_ret { }; struct xgetbv_ret xgetbv(void) - __asm__(GOSYM_PREFIX "internal..z2fcpu.xgetbv") + __asm__(GOSYM_PREFIX "internal_1cpu.xgetbv") __attribute__((no_split_stack)); #pragma GCC push_options @@ -82,7 +82,7 @@ struct queryResult { }; struct facilityList stfle(void) - __asm__(GOSYM_PREFIX "internal..z2fcpu.stfle") + __asm__(GOSYM_PREFIX "internal_1cpu.stfle") __attribute__((no_split_stack)); struct facilityList stfle(void) { @@ -96,7 +96,7 @@ struct facilityList stfle(void) { } struct queryResult kmQuery(void) - __asm__(GOSYM_PREFIX "internal..z2fcpu.kmQuery") + __asm__(GOSYM_PREFIX "internal_1cpu.kmQuery") __attribute__((no_split_stack)); struct queryResult kmQuery() { @@ -110,7 +110,7 @@ struct queryResult kmQuery() { } struct queryResult kmcQuery(void) - __asm__(GOSYM_PREFIX "internal..z2fcpu.kmcQuery") + __asm__(GOSYM_PREFIX "internal_1cpu.kmcQuery") __attribute__((no_split_stack)); struct queryResult kmcQuery() { @@ -125,7 +125,7 @@ struct queryResult kmcQuery() { } struct queryResult kmctrQuery(void) - __asm__(GOSYM_PREFIX "internal..z2fcpu.kmctrQuery") + __asm__(GOSYM_PREFIX "internal_1cpu.kmctrQuery") __attribute__((no_split_stack)); struct queryResult kmctrQuery() { @@ -140,7 +140,7 @@ struct queryResult kmctrQuery() { } struct queryResult kmaQuery(void) - __asm__(GOSYM_PREFIX "internal..z2fcpu.kmaQuery") + __asm__(GOSYM_PREFIX "internal_1cpu.kmaQuery") __attribute__((no_split_stack)); struct queryResult kmaQuery() { @@ -155,7 +155,7 @@ struct queryResult kmaQuery() { } struct queryResult kimdQuery(void) - __asm__(GOSYM_PREFIX "internal..z2fcpu.kimdQuery") + __asm__(GOSYM_PREFIX "internal_1cpu.kimdQuery") __attribute__((no_split_stack)); struct queryResult kimdQuery() { @@ -170,7 +170,7 @@ struct queryResult kimdQuery() { } struct queryResult klmdQuery(void) - __asm__(GOSYM_PREFIX "internal..z2fcpu.klmdQuery") + __asm__(GOSYM_PREFIX "internal_1cpu.klmdQuery") __attribute__((no_split_stack)); struct queryResult klmdQuery() { @@ -185,7 +185,7 @@ struct queryResult klmdQuery() { } struct queryResult kdsaQuery(void) - __asm__(GOSYM_PREFIX "internal..z2fcpu.kdsaQuery") + __asm__(GOSYM_PREFIX "internal_1cpu.kdsaQuery") __attribute__((no_split_stack)); struct queryResult kdsaQuery() { diff --git a/libgo/go/log/syslog/syslog_c.c b/libgo/go/log/syslog/syslog_c.c index 36e7694..329df40 100644 --- a/libgo/go/log/syslog/syslog_c.c +++ b/libgo/go/log/syslog/syslog_c.c @@ -12,7 +12,7 @@ can't represent a C varargs function in Go. */ void syslog_c(intgo, const char*) - __asm__ (GOSYM_PREFIX "log..z2fsyslog.syslog_c"); + __asm__ (GOSYM_PREFIX "log_1syslog.syslog_c"); void syslog_c (intgo priority, const char *msg) diff --git a/libgo/go/runtime/atomic_pointer.go b/libgo/go/runtime/atomic_pointer.go index 49b0f2b..0295913 100644 --- a/libgo/go/runtime/atomic_pointer.go +++ b/libgo/go/runtime/atomic_pointer.go @@ -39,10 +39,10 @@ func atomicstorep(ptr unsafe.Pointer, new unsafe.Pointer) { // We cannot just call the runtime routines, because the race detector expects // to be able to intercept the sync/atomic forms but not the runtime forms. -//go:linkname sync_atomic_StoreUintptr sync..z2fatomic.StoreUintptr +//go:linkname sync_atomic_StoreUintptr sync_1atomic.StoreUintptr func sync_atomic_StoreUintptr(ptr *uintptr, new uintptr) -//go:linkname sync_atomic_StorePointer sync..z2fatomic.StorePointer +//go:linkname sync_atomic_StorePointer sync_1atomic.StorePointer //go:nosplit func sync_atomic_StorePointer(ptr *unsafe.Pointer, new unsafe.Pointer) { if writeBarrier.enabled { @@ -51,10 +51,10 @@ func sync_atomic_StorePointer(ptr *unsafe.Pointer, new unsafe.Pointer) { sync_atomic_StoreUintptr((*uintptr)(unsafe.Pointer(ptr)), uintptr(new)) } -//go:linkname sync_atomic_SwapUintptr sync..z2fatomic.SwapUintptr +//go:linkname sync_atomic_SwapUintptr sync_1atomic.SwapUintptr func sync_atomic_SwapUintptr(ptr *uintptr, new uintptr) uintptr -//go:linkname sync_atomic_SwapPointer sync..z2fatomic.SwapPointer +//go:linkname sync_atomic_SwapPointer sync_1atomic.SwapPointer //go:nosplit func sync_atomic_SwapPointer(ptr *unsafe.Pointer, new unsafe.Pointer) unsafe.Pointer { if writeBarrier.enabled { @@ -64,10 +64,10 @@ func sync_atomic_SwapPointer(ptr *unsafe.Pointer, new unsafe.Pointer) unsafe.Poi return old } -//go:linkname sync_atomic_CompareAndSwapUintptr sync..z2fatomic.CompareAndSwapUintptr +//go:linkname sync_atomic_CompareAndSwapUintptr sync_1atomic.CompareAndSwapUintptr func sync_atomic_CompareAndSwapUintptr(ptr *uintptr, old, new uintptr) bool -//go:linkname sync_atomic_CompareAndSwapPointer sync..z2fatomic.CompareAndSwapPointer +//go:linkname sync_atomic_CompareAndSwapPointer sync_1atomic.CompareAndSwapPointer //go:nosplit func sync_atomic_CompareAndSwapPointer(ptr *unsafe.Pointer, old, new unsafe.Pointer) bool { if writeBarrier.enabled { diff --git a/libgo/go/runtime/chan.go b/libgo/go/runtime/chan.go index b909d47..8e104f1 100644 --- a/libgo/go/runtime/chan.go +++ b/libgo/go/runtime/chan.go @@ -774,7 +774,7 @@ func reflect_chanlen(c *hchan) int { return int(c.qcount) } -//go:linkname reflectlite_chanlen internal..z2freflectlite.chanlen +//go:linkname reflectlite_chanlen internal_1reflectlite.chanlen func reflectlite_chanlen(c *hchan) int { if c == nil { return 0 diff --git a/libgo/go/runtime/cpuprof.go b/libgo/go/runtime/cpuprof.go index d395210..43f0a67 100644 --- a/libgo/go/runtime/cpuprof.go +++ b/libgo/go/runtime/cpuprof.go @@ -189,7 +189,7 @@ func CPUProfile() []byte { panic("CPUProfile no longer available") } -//go:linkname runtime_pprof_runtime_cyclesPerSecond runtime..z2fpprof.runtime_cyclesPerSecond +//go:linkname runtime_pprof_runtime_cyclesPerSecond runtime_1pprof.runtime__cyclesPerSecond func runtime_pprof_runtime_cyclesPerSecond() int64 { return tickspersecond() } @@ -200,7 +200,7 @@ func runtime_pprof_runtime_cyclesPerSecond() int64 { // on has been returned, readProfile returns eof=true. // The caller must save the returned data and tags before calling readProfile again. // -//go:linkname runtime_pprof_readProfile runtime..z2fpprof.readProfile +//go:linkname runtime_pprof_readProfile runtime_1pprof.readProfile func runtime_pprof_readProfile() ([]uint64, []unsafe.Pointer, bool) { lock(&cpuprof.lock) log := cpuprof.log diff --git a/libgo/go/runtime/debug.go b/libgo/go/runtime/debug.go index 1202e36..ff76580 100644 --- a/libgo/go/runtime/debug.go +++ b/libgo/go/runtime/debug.go @@ -66,7 +66,7 @@ func NumGoroutine() int { // added. func Fieldtrack(map[string]bool) -//go:linkname debug_modinfo runtime..z2fdebug.modinfo +//go:linkname debug_modinfo runtime_1debug.modinfo func debug_modinfo() string { return modinfo } diff --git a/libgo/go/runtime/heapdump.go b/libgo/go/runtime/heapdump.go index e8f16e9..816d93c 100644 --- a/libgo/go/runtime/heapdump.go +++ b/libgo/go/runtime/heapdump.go @@ -16,7 +16,7 @@ import ( "unsafe" ) -//go:linkname runtime_debug_WriteHeapDump runtime..z2fdebug.WriteHeapDump +//go:linkname runtime_debug_WriteHeapDump runtime_1debug.WriteHeapDump func runtime_debug_WriteHeapDump(fd uintptr) { stopTheWorld("write heap dump") diff --git a/libgo/go/runtime/iface.go b/libgo/go/runtime/iface.go index 5667ddb..f9df1e0 100644 --- a/libgo/go/runtime/iface.go +++ b/libgo/go/runtime/iface.go @@ -505,7 +505,7 @@ func reflect_ifaceE2I(inter *interfacetype, e eface, dst *iface) { dst.data = e.data } -//go:linkname reflectlite_ifaceE2I internal..z2freflectlite.ifaceE2I +//go:linkname reflectlite_ifaceE2I internal_1reflectlite.ifaceE2I func reflectlite_ifaceE2I(inter *interfacetype, e eface, dst *iface) { t := e._type if t == nil { diff --git a/libgo/go/runtime/internal/atomic/atomic.c b/libgo/go/runtime/internal/atomic/atomic.c index 8ae4d7b..9fed1a8 100644 --- a/libgo/go/runtime/internal/atomic/atomic.c +++ b/libgo/go/runtime/internal/atomic/atomic.c @@ -7,7 +7,7 @@ #include "runtime.h" uint32_t Load (uint32_t *ptr) - __asm__ (GOSYM_PREFIX "runtime..z2finternal..z2fatomic.Load") + __asm__ (GOSYM_PREFIX "runtime_1internal_1atomic.Load") __attribute__ ((no_split_stack)); uint32_t @@ -17,7 +17,7 @@ Load (uint32_t *ptr) } void *Loadp (void *ptr) - __asm__ (GOSYM_PREFIX "runtime..z2finternal..z2fatomic.Loadp") + __asm__ (GOSYM_PREFIX "runtime_1internal_1atomic.Loadp") __attribute__ ((no_split_stack)); void * @@ -27,7 +27,7 @@ Loadp (void *ptr) } uint8_t Load8 (uint8_t *ptr) - __asm__ (GOSYM_PREFIX "runtime..z2finternal..z2fatomic.Load8") + __asm__ (GOSYM_PREFIX "runtime_1internal_1atomic.Load8") __attribute__ ((no_split_stack)); uint8_t @@ -37,7 +37,7 @@ Load8 (uint8_t *ptr) } uint64_t Load64 (uint64_t *ptr) - __asm__ (GOSYM_PREFIX "runtime..z2finternal..z2fatomic.Load64") + __asm__ (GOSYM_PREFIX "runtime_1internal_1atomic.Load64") __attribute__ ((no_split_stack)); uint64_t @@ -49,7 +49,7 @@ Load64 (uint64_t *ptr) } uint32_t LoadAcq (uint32_t *ptr) - __asm__ (GOSYM_PREFIX "runtime..z2finternal..z2fatomic.LoadAcq") + __asm__ (GOSYM_PREFIX "runtime_1internal_1atomic.LoadAcq") __attribute__ ((no_split_stack)); uint32_t @@ -59,7 +59,7 @@ LoadAcq (uint32_t *ptr) } uintptr_t Loaduintptr (uintptr_t *ptr) - __asm__ (GOSYM_PREFIX "runtime..z2finternal..z2fatomic.Loaduintptr") + __asm__ (GOSYM_PREFIX "runtime_1internal_1atomic.Loaduintptr") __attribute__ ((no_split_stack)); uintptr_t @@ -69,7 +69,7 @@ Loaduintptr (uintptr_t *ptr) } uintgo Loaduint (uintgo *ptr) - __asm__ (GOSYM_PREFIX "runtime..z2finternal..z2fatomic.Loaduint") + __asm__ (GOSYM_PREFIX "runtime_1internal_1atomic.Loaduint") __attribute__ ((no_split_stack)); uintgo @@ -79,7 +79,7 @@ Loaduint (uintgo *ptr) } int64_t Loadint64 (int64_t *ptr) - __asm__ (GOSYM_PREFIX "runtime..z2finternal..z2fatomic.Loadint64") + __asm__ (GOSYM_PREFIX "runtime_1internal_1atomic.Loadint64") __attribute__ ((no_split_stack)); int64_t @@ -91,7 +91,7 @@ Loadint64 (int64_t *ptr) } uint32_t Xadd (uint32_t *ptr, int32_t delta) - __asm__ (GOSYM_PREFIX "runtime..z2finternal..z2fatomic.Xadd") + __asm__ (GOSYM_PREFIX "runtime_1internal_1atomic.Xadd") __attribute__ ((no_split_stack)); uint32_t @@ -101,7 +101,7 @@ Xadd (uint32_t *ptr, int32_t delta) } uint64_t Xadd64 (uint64_t *ptr, int64_t delta) - __asm__ (GOSYM_PREFIX "runtime..z2finternal..z2fatomic.Xadd64") + __asm__ (GOSYM_PREFIX "runtime_1internal_1atomic.Xadd64") __attribute__ ((no_split_stack)); uint64_t @@ -113,7 +113,7 @@ Xadd64 (uint64_t *ptr, int64_t delta) } uintptr_t Xadduintptr (uintptr_t *ptr, uintptr_t delta) - __asm__ (GOSYM_PREFIX "runtime..z2finternal..z2fatomic.Xadduintptr") + __asm__ (GOSYM_PREFIX "runtime_1internal_1atomic.Xadduintptr") __attribute__ ((no_split_stack)); uintptr_t @@ -123,7 +123,7 @@ Xadduintptr (uintptr_t *ptr, uintptr_t delta) } int64_t Xaddint64 (int64_t *ptr, int64_t delta) - __asm__ (GOSYM_PREFIX "runtime..z2finternal..z2fatomic.Xaddint64") + __asm__ (GOSYM_PREFIX "runtime_1internal_1atomic.Xaddint64") __attribute__ ((no_split_stack)); int64_t @@ -135,7 +135,7 @@ Xaddint64 (int64_t *ptr, int64_t delta) } uint32_t Xchg (uint32_t *ptr, uint32_t new) - __asm__ (GOSYM_PREFIX "runtime..z2finternal..z2fatomic.Xchg") + __asm__ (GOSYM_PREFIX "runtime_1internal_1atomic.Xchg") __attribute__ ((no_split_stack)); uint32_t @@ -145,7 +145,7 @@ Xchg (uint32_t *ptr, uint32_t new) } uint64_t Xchg64 (uint64_t *ptr, uint64_t new) - __asm__ (GOSYM_PREFIX "runtime..z2finternal..z2fatomic.Xchg64") + __asm__ (GOSYM_PREFIX "runtime_1internal_1atomic.Xchg64") __attribute__ ((no_split_stack)); uint64_t @@ -157,7 +157,7 @@ Xchg64 (uint64_t *ptr, uint64_t new) } uintptr_t Xchguintptr (uintptr_t *ptr, uintptr_t new) - __asm__ (GOSYM_PREFIX "runtime..z2finternal..z2fatomic.Xchguintptr") + __asm__ (GOSYM_PREFIX "runtime_1internal_1atomic.Xchguintptr") __attribute__ ((no_split_stack)); uintptr_t @@ -167,7 +167,7 @@ Xchguintptr (uintptr_t *ptr, uintptr_t new) } void And8 (uint8_t *ptr, uint8_t val) - __asm__ (GOSYM_PREFIX "runtime..z2finternal..z2fatomic.And8") + __asm__ (GOSYM_PREFIX "runtime_1internal_1atomic.And8") __attribute__ ((no_split_stack)); void @@ -177,7 +177,7 @@ And8 (uint8_t *ptr, uint8_t val) } void Or8 (uint8_t *ptr, uint8_t val) - __asm__ (GOSYM_PREFIX "runtime..z2finternal..z2fatomic.Or8") + __asm__ (GOSYM_PREFIX "runtime_1internal_1atomic.Or8") __attribute__ ((no_split_stack)); void @@ -187,7 +187,7 @@ Or8 (uint8_t *ptr, uint8_t val) } _Bool Cas (uint32_t *ptr, uint32_t old, uint32_t new) - __asm__ (GOSYM_PREFIX "runtime..z2finternal..z2fatomic.Cas") + __asm__ (GOSYM_PREFIX "runtime_1internal_1atomic.Cas") __attribute__ ((no_split_stack)); _Bool @@ -197,7 +197,7 @@ Cas (uint32_t *ptr, uint32_t old, uint32_t new) } _Bool Cas64 (uint64_t *ptr, uint64_t old, uint64_t new) - __asm__ (GOSYM_PREFIX "runtime..z2finternal..z2fatomic.Cas64") + __asm__ (GOSYM_PREFIX "runtime_1internal_1atomic.Cas64") __attribute__ ((no_split_stack)); _Bool @@ -209,7 +209,7 @@ Cas64 (uint64_t *ptr, uint64_t old, uint64_t new) } _Bool CasRel (uint32_t *ptr, uint32_t old, uint32_t new) - __asm__ (GOSYM_PREFIX "runtime..z2finternal..z2fatomic.CasRel") + __asm__ (GOSYM_PREFIX "runtime_1internal_1atomic.CasRel") __attribute__ ((no_split_stack)); _Bool @@ -219,7 +219,7 @@ CasRel (uint32_t *ptr, uint32_t old, uint32_t new) } _Bool Casp1 (void **ptr, void *old, void *new) - __asm__ (GOSYM_PREFIX "runtime..z2finternal..z2fatomic.Casp1") + __asm__ (GOSYM_PREFIX "runtime_1internal_1atomic.Casp1") __attribute__ ((no_split_stack)); _Bool @@ -229,7 +229,7 @@ Casp1 (void **ptr, void *old, void *new) } _Bool Casuintptr (uintptr_t *ptr, uintptr_t old, uintptr_t new) - __asm__ (GOSYM_PREFIX "runtime..z2finternal..z2fatomic.Casuintptr") + __asm__ (GOSYM_PREFIX "runtime_1internal_1atomic.Casuintptr") __attribute__ ((no_split_stack)); _Bool @@ -239,7 +239,7 @@ Casuintptr (uintptr_t *ptr, uintptr_t old, uintptr_t new) } void Store (uint32_t *ptr, uint32_t val) - __asm__ (GOSYM_PREFIX "runtime..z2finternal..z2fatomic.Store") + __asm__ (GOSYM_PREFIX "runtime_1internal_1atomic.Store") __attribute__ ((no_split_stack)); void @@ -249,7 +249,7 @@ Store (uint32_t *ptr, uint32_t val) } void Store8 (uint8_t *ptr, uint8_t val) - __asm__ (GOSYM_PREFIX "runtime..z2finternal..z2fatomic.Store8") + __asm__ (GOSYM_PREFIX "runtime_1internal_1atomic.Store8") __attribute__ ((no_split_stack)); void @@ -259,7 +259,7 @@ Store8 (uint8_t *ptr, uint8_t val) } void Store64 (uint64_t *ptr, uint64_t val) - __asm__ (GOSYM_PREFIX "runtime..z2finternal..z2fatomic.Store64") + __asm__ (GOSYM_PREFIX "runtime_1internal_1atomic.Store64") __attribute__ ((no_split_stack)); void @@ -271,7 +271,7 @@ Store64 (uint64_t *ptr, uint64_t val) } void StoreRel (uint32_t *ptr, uint32_t val) - __asm__ (GOSYM_PREFIX "runtime..z2finternal..z2fatomic.StoreRel") + __asm__ (GOSYM_PREFIX "runtime_1internal_1atomic.StoreRel") __attribute__ ((no_split_stack)); void @@ -281,7 +281,7 @@ StoreRel (uint32_t *ptr, uint32_t val) } void Storeuintptr (uintptr_t *ptr, uintptr_t val) - __asm__ (GOSYM_PREFIX "runtime..z2finternal..z2fatomic.Storeuintptr") + __asm__ (GOSYM_PREFIX "runtime_1internal_1atomic.Storeuintptr") __attribute__ ((no_split_stack)); void @@ -291,7 +291,7 @@ Storeuintptr (uintptr_t *ptr, uintptr_t val) } void StorepNoWB (void *ptr, void *val) - __asm__ (GOSYM_PREFIX "runtime..z2finternal..z2fatomic.StorepNoWB") + __asm__ (GOSYM_PREFIX "runtime_1internal_1atomic.StorepNoWB") __attribute__ ((no_split_stack)); void diff --git a/libgo/go/runtime/malloc.go b/libgo/go/runtime/malloc.go index 81351ee..feb043a 100644 --- a/libgo/go/runtime/malloc.go +++ b/libgo/go/runtime/malloc.go @@ -1220,12 +1220,12 @@ func newobject(typ *_type) unsafe.Pointer { return mallocgc(typ.size, typ, true) } -//go:linkname reflect_unsafe_New reflect.unsafe_New +//go:linkname reflect_unsafe_New reflect.unsafe__New func reflect_unsafe_New(typ *_type) unsafe.Pointer { return mallocgc(typ.size, typ, true) } -//go:linkname reflectlite_unsafe_New internal..z2freflectlite.unsafe_New +//go:linkname reflectlite_unsafe_New internal_1reflectlite.unsafe__New func reflectlite_unsafe_New(typ *_type) unsafe.Pointer { return mallocgc(typ.size, typ, true) } @@ -1242,7 +1242,7 @@ func newarray(typ *_type, n int) unsafe.Pointer { return mallocgc(mem, typ, true) } -//go:linkname reflect_unsafe_NewArray reflect.unsafe_NewArray +//go:linkname reflect_unsafe_NewArray reflect.unsafe__NewArray func reflect_unsafe_NewArray(typ *_type, n int) unsafe.Pointer { return newarray(typ, n) } diff --git a/libgo/go/runtime/map.go b/libgo/go/runtime/map.go index b829771..1155fee 100644 --- a/libgo/go/runtime/map.go +++ b/libgo/go/runtime/map.go @@ -1417,7 +1417,7 @@ func reflect_maplen(h *hmap) int { return h.count } -//go:linkname reflectlite_maplen internal..z2freflectlite.maplen +//go:linkname reflectlite_maplen internal_1reflectlite.maplen func reflectlite_maplen(h *hmap) int { if h == nil { return 0 diff --git a/libgo/go/runtime/mbarrier.go b/libgo/go/runtime/mbarrier.go index 836f85a..3bd8b34 100644 --- a/libgo/go/runtime/mbarrier.go +++ b/libgo/go/runtime/mbarrier.go @@ -192,7 +192,7 @@ func reflect_typedmemmove(typ *_type, dst, src unsafe.Pointer) { typedmemmove(typ, dst, src) } -//go:linkname reflectlite_typedmemmove internal..z2freflectlite.typedmemmove +//go:linkname reflectlite_typedmemmove internal_1reflectlite.typedmemmove func reflectlite_typedmemmove(typ *_type, dst, src unsafe.Pointer) { reflect_typedmemmove(typ, dst, src) } diff --git a/libgo/go/runtime/mgc.go b/libgo/go/runtime/mgc.go index 9dd7bff..72479c2 100644 --- a/libgo/go/runtime/mgc.go +++ b/libgo/go/runtime/mgc.go @@ -223,7 +223,7 @@ func gcenable() { memstats.enablegc = true // now that runtime is initialized, GC is okay } -//go:linkname setGCPercent runtime..z2fdebug.setGCPercent +//go:linkname setGCPercent runtime_1debug.setGCPercent func setGCPercent(in int32) (out int32) { // Run on the system stack since we grab the heap lock. systemstack(func() { @@ -2238,7 +2238,7 @@ func gcResetMarkState() { var poolcleanup func() -//go:linkname sync_runtime_registerPoolCleanup sync.runtime_registerPoolCleanup +//go:linkname sync_runtime_registerPoolCleanup sync.runtime__registerPoolCleanup func sync_runtime_registerPoolCleanup(f func()) { poolcleanup = f } diff --git a/libgo/go/runtime/mheap.go b/libgo/go/runtime/mheap.go index e73ee32..755efd1 100644 --- a/libgo/go/runtime/mheap.go +++ b/libgo/go/runtime/mheap.go @@ -1502,7 +1502,7 @@ func (h *mheap) scavengeAll() { } } -//go:linkname runtime_debug_freeOSMemory runtime..z2fdebug.freeOSMemory +//go:linkname runtime_debug_freeOSMemory runtime_1debug.freeOSMemory func runtime_debug_freeOSMemory() { GC() systemstack(func() { mheap_.scavengeAll() }) diff --git a/libgo/go/runtime/mprof.go b/libgo/go/runtime/mprof.go index a4b135d..afacf8f 100644 --- a/libgo/go/runtime/mprof.go +++ b/libgo/go/runtime/mprof.go @@ -942,7 +942,7 @@ func ThreadCreateProfile(p []StackRecord) (n int, ok bool) { return } -//go:linkname runtime_goroutineProfileWithLabels runtime..z2fpprof.runtime_goroutineProfileWithLabels +//go:linkname runtime_goroutineProfileWithLabels runtime_1pprof.runtime__goroutineProfileWithLabels func runtime_goroutineProfileWithLabels(p []StackRecord, labels []unsafe.Pointer) (n int, ok bool) { return goroutineProfileWithLabels(p, labels) } diff --git a/libgo/go/runtime/mstats.go b/libgo/go/runtime/mstats.go index 4e2c66ce..85a0861 100644 --- a/libgo/go/runtime/mstats.go +++ b/libgo/go/runtime/mstats.go @@ -468,7 +468,7 @@ func readmemstats_m(stats *MemStats) { stats.StackSys += stats.StackInuse } -//go:linkname readGCStats runtime..z2fdebug.readGCStats +//go:linkname readGCStats runtime_1debug.readGCStats func readGCStats(pauses *[]uint64) { systemstack(func() { readGCStats_m(pauses) diff --git a/libgo/go/runtime/net_plan9.go b/libgo/go/runtime/net_plan9.go index 907c319..38ff5a4 100644 --- a/libgo/go/runtime/net_plan9.go +++ b/libgo/go/runtime/net_plan9.go @@ -8,12 +8,12 @@ import ( _ "unsafe" ) -//go:linkname runtime_ignoreHangup internal..z2fpoll.runtime_ignoreHangup +//go:linkname runtime_ignoreHangup internal_1poll.runtime__ignoreHangup func runtime_ignoreHangup() { getg().m.ignoreHangup = true } -//go:linkname runtime_unignoreHangup internal..z2fpoll.runtime_unignoreHangup +//go:linkname runtime_unignoreHangup internal_1poll.runtime__unignoreHangup func runtime_unignoreHangup(sig string) { getg().m.ignoreHangup = false } diff --git a/libgo/go/runtime/netpoll.go b/libgo/go/runtime/netpoll.go index 72a136d..da00b57 100644 --- a/libgo/go/runtime/netpoll.go +++ b/libgo/go/runtime/netpoll.go @@ -113,7 +113,7 @@ var ( netpollWaiters uint32 ) -//go:linkname poll_runtime_pollServerInit internal..z2fpoll.runtime_pollServerInit +//go:linkname poll_runtime_pollServerInit internal_1poll.runtime__pollServerInit func poll_runtime_pollServerInit() { netpollGenericInit() } @@ -134,7 +134,7 @@ func netpollinited() bool { return atomic.Load(&netpollInited) != 0 } -//go:linkname poll_runtime_isPollServerDescriptor internal..z2fpoll.runtime_isPollServerDescriptor +//go:linkname poll_runtime_isPollServerDescriptor internal_1poll.runtime__isPollServerDescriptor // poll_runtime_isPollServerDescriptor reports whether fd is a // descriptor being used by netpoll. @@ -142,7 +142,7 @@ func poll_runtime_isPollServerDescriptor(fd uintptr) bool { return netpollIsPollDescriptor(fd) } -//go:linkname poll_runtime_pollOpen internal..z2fpoll.runtime_pollOpen +//go:linkname poll_runtime_pollOpen internal_1poll.runtime__pollOpen func poll_runtime_pollOpen(fd uintptr) (uintptr, int) { pd := pollcache.alloc() lock(&pd.lock) @@ -169,7 +169,7 @@ func poll_runtime_pollOpen(fd uintptr) (uintptr, int) { return uintptr(unsafe.Pointer(pd)), int(errno) } -//go:linkname poll_runtime_pollClose internal..z2fpoll.runtime_pollClose +//go:linkname poll_runtime_pollClose internal_1poll.runtime__pollClose func poll_runtime_pollClose(ctx uintptr) { pd := (*pollDesc)(unsafe.Pointer(ctx)) if !pd.closing { @@ -195,7 +195,7 @@ func (c *pollCache) free(pd *pollDesc) { // poll_runtime_pollReset, which is internal/poll.runtime_pollReset, // prepares a descriptor for polling in mode, which is 'r' or 'w'. // This returns an error code; the codes are defined above. -//go:linkname poll_runtime_pollReset internal..z2fpoll.runtime_pollReset +//go:linkname poll_runtime_pollReset internal_1poll.runtime__pollReset func poll_runtime_pollReset(ctx uintptr, mode int) int { pd := (*pollDesc)(unsafe.Pointer(ctx)) errcode := netpollcheckerr(pd, int32(mode)) @@ -214,7 +214,7 @@ func poll_runtime_pollReset(ctx uintptr, mode int) int { // waits for a descriptor to be ready for reading or writing, // according to mode, which is 'r' or 'w'. // This returns an error code; the codes are defined above. -//go:linkname poll_runtime_pollWait internal..z2fpoll.runtime_pollWait +//go:linkname poll_runtime_pollWait internal_1poll.runtime__pollWait func poll_runtime_pollWait(ctx uintptr, mode int) int { pd := (*pollDesc)(unsafe.Pointer(ctx)) errcode := netpollcheckerr(pd, int32(mode)) @@ -237,7 +237,7 @@ func poll_runtime_pollWait(ctx uintptr, mode int) int { return pollNoError } -//go:linkname poll_runtime_pollWaitCanceled internal..z2fpoll.runtime_pollWaitCanceled +//go:linkname poll_runtime_pollWaitCanceled internal_1poll.runtime__pollWaitCanceled func poll_runtime_pollWaitCanceled(ctx uintptr, mode int) { pd := (*pollDesc)(unsafe.Pointer(ctx)) // This function is used only on windows after a failed attempt to cancel @@ -246,7 +246,7 @@ func poll_runtime_pollWaitCanceled(ctx uintptr, mode int) { } } -//go:linkname poll_runtime_pollSetDeadline internal..z2fpoll.runtime_pollSetDeadline +//go:linkname poll_runtime_pollSetDeadline internal_1poll.runtime__pollSetDeadline func poll_runtime_pollSetDeadline(ctx uintptr, d int64, mode int) { pd := (*pollDesc)(unsafe.Pointer(ctx)) lock(&pd.lock) @@ -330,7 +330,7 @@ func poll_runtime_pollSetDeadline(ctx uintptr, d int64, mode int) { } } -//go:linkname poll_runtime_pollUnblock internal..z2fpoll.runtime_pollUnblock +//go:linkname poll_runtime_pollUnblock internal_1poll.runtime__pollUnblock func poll_runtime_pollUnblock(ctx uintptr) { pd := (*pollDesc)(unsafe.Pointer(ctx)) lock(&pd.lock) diff --git a/libgo/go/runtime/pprof/mprof_test.go b/libgo/go/runtime/pprof/mprof_test.go index 625ab7d..83bf572 100644 --- a/libgo/go/runtime/pprof/mprof_test.go +++ b/libgo/go/runtime/pprof/mprof_test.go @@ -91,35 +91,35 @@ func TestMemoryProfiler(t *testing.T) { stk []string legacy string }{{ - stk: []string{"pprof.allocatePersistent1K", "runtime/pprof.TestMemoryProfiler"}, + stk: []string{"runtime/pprof.allocatePersistent1K", "runtime/pprof.TestMemoryProfiler"}, legacy: fmt.Sprintf(`%v: %v \[%v: %v\] @ 0x[0-9,a-f x]+ -# 0x[0-9,a-f]+ pprof\.allocatePersistent1K\+0x[0-9,a-f]+ .*/mprof_test\.go:47 +# 0x[0-9,a-f]+ runtime/pprof\.allocatePersistent1K\+0x[0-9,a-f]+ .*/mprof_test\.go:47 # 0x[0-9,a-f]+ runtime/pprof\.TestMemoryProfiler\+0x[0-9,a-f]+ .*/mprof_test\.go:82 `, 32*memoryProfilerRun, 1024*memoryProfilerRun, 32*memoryProfilerRun, 1024*memoryProfilerRun), }, { - stk: []string{"pprof.allocateTransient1M", "runtime/pprof.TestMemoryProfiler"}, + stk: []string{"runtime/pprof.allocateTransient1M", "runtime/pprof.TestMemoryProfiler"}, legacy: fmt.Sprintf(`(0|%v): (0|%v) \[%v: %v\] @ 0x[0-9,a-f x]+ -# 0x[0-9,a-f]+ pprof\.allocateTransient1M\+0x[0-9,a-f]+ .*/mprof_test.go:24 +# 0x[0-9,a-f]+ runtime/pprof\.allocateTransient1M\+0x[0-9,a-f]+ .*/mprof_test.go:24 # 0x[0-9,a-f]+ runtime/pprof\.TestMemoryProfiler\+0x[0-9,a-f]+ .*/mprof_test.go:79 `, (1<<10)*memoryProfilerRun, (1<<20)*memoryProfilerRun, (1<<10)*memoryProfilerRun, (1<<20)*memoryProfilerRun), }, { - stk: []string{"pprof.allocateTransient2M", "runtime/pprof.TestMemoryProfiler"}, + stk: []string{"runtime/pprof.allocateTransient2M", "runtime/pprof.TestMemoryProfiler"}, // This should start with "0: 0" but gccgo's imprecise // GC means that sometimes the value is not collected. legacy: fmt.Sprintf(`(0|%v): (0|%v) \[%v: %v\] @ 0x[0-9,a-f x]+ -# 0x[0-9,a-f]+ pprof\.allocateTransient2M\+0x[0-9,a-f]+ .*/mprof_test.go:30 +# 0x[0-9,a-f]+ runtime/pprof\.allocateTransient2M\+0x[0-9,a-f]+ .*/mprof_test.go:30 # 0x[0-9,a-f]+ runtime/pprof\.TestMemoryProfiler\+0x[0-9,a-f]+ .*/mprof_test.go:80 `, memoryProfilerRun, (2<<20)*memoryProfilerRun, memoryProfilerRun, (2<<20)*memoryProfilerRun), }, { - stk: []string{"pprof.allocateTransient2MInline", "runtime/pprof.TestMemoryProfiler"}, + stk: []string{"runtime/pprof.allocateTransient2MInline", "runtime/pprof.TestMemoryProfiler"}, legacy: fmt.Sprintf(`(0|%v): (0|%v) \[%v: %v\] @ 0x[0-9,a-f x]+ -# 0x[0-9,a-f]+ pprof\.allocateTransient2MInline\+0x[0-9,a-f]+ .*/mprof_test.go:34 +# 0x[0-9,a-f]+ runtime/pprof\.allocateTransient2MInline\+0x[0-9,a-f]+ .*/mprof_test.go:34 # 0x[0-9,a-f]+ runtime/pprof\.TestMemoryProfiler\+0x[0-9,a-f]+ .*/mprof_test.go:81 `, memoryProfilerRun, (4<<20)*memoryProfilerRun, memoryProfilerRun, (4<<20)*memoryProfilerRun), }, { - stk: []string{"pprof.allocateReflectTransient"}, + stk: []string{"runtime/pprof.allocateReflectTransient"}, legacy: fmt.Sprintf(`(0|%v): (0|%v) \[%v: %v\] @( 0x[0-9,a-f]+)+ -# 0x[0-9,a-f]+ pprof\.allocateReflectTransient\+0x[0-9,a-f]+ .*/mprof_test.go:55 +# 0x[0-9,a-f]+ runtime/pprof\.allocateReflectTransient\+0x[0-9,a-f]+ .*/mprof_test.go:55 `, memoryProfilerRun, (3<<20)*memoryProfilerRun, memoryProfilerRun, (3<<20)*memoryProfilerRun), }} diff --git a/libgo/go/runtime/pprof/pprof_test.go b/libgo/go/runtime/pprof/pprof_test.go index ff86bce..7adf891 100644 --- a/libgo/go/runtime/pprof/pprof_test.go +++ b/libgo/go/runtime/pprof/pprof_test.go @@ -958,8 +958,8 @@ func TestMutexProfile(t *testing.T) { stks := stacks(p) for _, want := range [][]string{ - // {"sync.(*Mutex).Unlock", "pprof.blockMutex.func1"}, - {"sync.Mutex.Unlock", "pprof.blockMutex..func1"}, + // {"sync.(*Mutex).Unlock", "runtime/pprof.blockMutex.func1"}, + {"sync.Mutex.Unlock", "runtime/pprof.blockMutex..func1"}, } { if !containsStack(stks, want) { t.Errorf("No matching stack entry for %+v", want) diff --git a/libgo/go/runtime/preempt.go b/libgo/go/runtime/preempt.go index 9a78bcf..8452076 100644 --- a/libgo/go/runtime/preempt.go +++ b/libgo/go/runtime/preempt.go @@ -360,7 +360,7 @@ func isAsyncSafePoint(gp *g, pc uintptr) (bool, uintptr) { } name := f.Name() if hasPrefix(name, "runtime.") || - hasPrefix(name, "runtime..z2finternal..z2f") || + hasPrefix(name, "runtime_1internal_1") || hasPrefix(name, "reflect.") { // For now we never async preempt the runtime or // anything closely tied to the runtime. Known issues diff --git a/libgo/go/runtime/proc.go b/libgo/go/runtime/proc.go index 0ca6c02..6c72050 100644 --- a/libgo/go/runtime/proc.go +++ b/libgo/go/runtime/proc.go @@ -263,7 +263,7 @@ func main(unsafe.Pointer) { } // os_beforeExit is called from os.Exit(0). -//go:linkname os_beforeExit os.runtime_beforeExit +//go:linkname os_beforeExit os.runtime__beforeExit func os_beforeExit() { if raceenabled { racefini() @@ -3305,7 +3305,7 @@ func beforefork() { } // Called from syscall package before fork. -//go:linkname syscall_runtime_BeforeFork syscall.runtime_BeforeFork +//go:linkname syscall_runtime_BeforeFork syscall.runtime__BeforeFork //go:nosplit func syscall_runtime_BeforeFork() { systemstack(beforefork) @@ -3320,7 +3320,7 @@ func afterfork() { } // Called from syscall package after fork in parent. -//go:linkname syscall_runtime_AfterFork syscall.runtime_AfterFork +//go:linkname syscall_runtime_AfterFork syscall.runtime__AfterFork //go:nosplit func syscall_runtime_AfterFork() { systemstack(afterfork) @@ -3338,7 +3338,7 @@ var inForkedChild bool // temporarily sharing address space with the parent process, this must // not change any global variables or calling into C code that may do so. // -//go:linkname syscall_runtime_AfterForkInChild syscall.runtime_AfterForkInChild +//go:linkname syscall_runtime_AfterForkInChild syscall.runtime__AfterForkInChild //go:nosplit //go:nowritebarrierrec func syscall_runtime_AfterForkInChild() { @@ -3363,7 +3363,7 @@ func syscall_runtime_AfterForkInChild() { var pendingPreemptSignals uint32 // Called from syscall package before Exec. -//go:linkname syscall_runtime_BeforeExec syscall.runtime_BeforeExec +//go:linkname syscall_runtime_BeforeExec syscall.runtime__BeforeExec func syscall_runtime_BeforeExec() { // Prevent thread creation during exec. execLock.lock() @@ -3378,7 +3378,7 @@ func syscall_runtime_BeforeExec() { } // Called from syscall package after Exec. -//go:linkname syscall_runtime_AfterExec syscall.runtime_AfterExec +//go:linkname syscall_runtime_AfterExec syscall.runtime__AfterExec func syscall_runtime_AfterExec() { execLock.unlock() } @@ -5165,7 +5165,7 @@ func (l *gList) pop() *g { return gp } -//go:linkname setMaxThreads runtime..z2fdebug.setMaxThreads +//go:linkname setMaxThreads runtime_1debug.setMaxThreads func setMaxThreads(in int) (out int) { lock(&sched.lock) out = int(sched.maxmcount) @@ -5199,32 +5199,32 @@ func procUnpin() { _g_.m.locks-- } -//go:linkname sync_runtime_procPin sync.runtime_procPin +//go:linkname sync_runtime_procPin sync.runtime__procPin //go:nosplit func sync_runtime_procPin() int { return procPin() } -//go:linkname sync_runtime_procUnpin sync.runtime_procUnpin +//go:linkname sync_runtime_procUnpin sync.runtime__procUnpin //go:nosplit func sync_runtime_procUnpin() { procUnpin() } -//go:linkname sync_atomic_runtime_procPin sync..z2fatomic.runtime_procPin +//go:linkname sync_atomic_runtime_procPin sync_1atomic.runtime__procPin //go:nosplit func sync_atomic_runtime_procPin() int { return procPin() } -//go:linkname sync_atomic_runtime_procUnpin sync..z2fatomic.runtime_procUnpin +//go:linkname sync_atomic_runtime_procUnpin sync_1atomic.runtime__procUnpin //go:nosplit func sync_atomic_runtime_procUnpin() { procUnpin() } // Active spinning for sync.Mutex. -//go:linkname sync_runtime_canSpin sync.runtime_canSpin +//go:linkname sync_runtime_canSpin sync.runtime__canSpin //go:nosplit func sync_runtime_canSpin(i int) bool { // sync.Mutex is cooperative, so we are conservative with spinning. @@ -5241,7 +5241,7 @@ func sync_runtime_canSpin(i int) bool { return true } -//go:linkname sync_runtime_doSpin sync.runtime_doSpin +//go:linkname sync_runtime_doSpin sync.runtime__doSpin //go:nosplit func sync_runtime_doSpin() { procyield(active_spin_cnt) diff --git a/libgo/go/runtime/proflabel.go b/libgo/go/runtime/proflabel.go index fc655cc..1e1f3bf 100644 --- a/libgo/go/runtime/proflabel.go +++ b/libgo/go/runtime/proflabel.go @@ -8,7 +8,7 @@ import "unsafe" var labelSync uintptr -//go:linkname runtime_setProfLabel runtime..z2fpprof.runtime_setProfLabel +//go:linkname runtime_setProfLabel runtime_1pprof.runtime__setProfLabel func runtime_setProfLabel(labels unsafe.Pointer) { // Introduce race edge for read-back via profile. // This would more properly use &getg().labels as the sync address, @@ -34,7 +34,7 @@ func runtime_setProfLabel(labels unsafe.Pointer) { getg().labels = labels } -//go:linkname runtime_getProfLabel runtime..z2fpprof.runtime_getProfLabel +//go:linkname runtime_getProfLabel runtime_1pprof.runtime__getProfLabel func runtime_getProfLabel() unsafe.Pointer { return getg().labels } diff --git a/libgo/go/runtime/rdebug.go b/libgo/go/runtime/rdebug.go index 358df11..9c43ce5 100644 --- a/libgo/go/runtime/rdebug.go +++ b/libgo/go/runtime/rdebug.go @@ -11,14 +11,14 @@ import _ "unsafe" // for go:linkname // maxstacksize. var maxstacksize uintptr = 1 << 20 // enough until runtime.main sets it for real -//go:linkname setMaxStack runtime..z2fdebug.setMaxStack +//go:linkname setMaxStack runtime_1debug.setMaxStack func setMaxStack(in int) (out int) { out = int(maxstacksize) maxstacksize = uintptr(in) return out } -//go:linkname setPanicOnFault runtime..z2fdebug.setPanicOnFault +//go:linkname setPanicOnFault runtime_1debug.setPanicOnFault func setPanicOnFault(new bool) (old bool) { _g_ := getg() old = _g_.paniconfault diff --git a/libgo/go/runtime/runtime.go b/libgo/go/runtime/runtime.go index abc5eab..5af28ae 100644 --- a/libgo/go/runtime/runtime.go +++ b/libgo/go/runtime/runtime.go @@ -51,13 +51,13 @@ func tickspersecond() int64 { var envs []string var argslice []string -//go:linkname syscall_runtime_envs syscall.runtime_envs +//go:linkname syscall_runtime_envs syscall.runtime__envs func syscall_runtime_envs() []string { return append([]string{}, envs...) } //go:linkname syscall_Getpagesize syscall.Getpagesize func syscall_Getpagesize() int { return int(physPageSize) } -//go:linkname os_runtime_args os.runtime_args +//go:linkname os_runtime_args os.runtime__args func os_runtime_args() []string { return append([]string{}, argslice...) } //go:linkname syscall_Exit syscall.Exit diff --git a/libgo/go/runtime/runtime1.go b/libgo/go/runtime/runtime1.go index a8a53d3..39969d1 100644 --- a/libgo/go/runtime/runtime1.go +++ b/libgo/go/runtime/runtime1.go @@ -398,7 +398,7 @@ func parsedebugvars() { traceback_env = traceback_cache } -//go:linkname setTraceback runtime..z2fdebug.SetTraceback +//go:linkname setTraceback runtime_1debug.SetTraceback func setTraceback(level string) { var t uint32 switch level { diff --git a/libgo/go/runtime/sema.go b/libgo/go/runtime/sema.go index c1418b3..9a28880 100644 --- a/libgo/go/runtime/sema.go +++ b/libgo/go/runtime/sema.go @@ -51,27 +51,27 @@ var semtable [semTabSize]struct { pad [cpu.CacheLinePadSize - unsafe.Sizeof(semaRoot{})]byte } -//go:linkname sync_runtime_Semacquire sync.runtime_Semacquire +//go:linkname sync_runtime_Semacquire sync.runtime__Semacquire func sync_runtime_Semacquire(addr *uint32) { semacquire1(addr, false, semaBlockProfile, 0) } -//go:linkname poll_runtime_Semacquire internal..z2fpoll.runtime_Semacquire +//go:linkname poll_runtime_Semacquire internal_1poll.runtime__Semacquire func poll_runtime_Semacquire(addr *uint32) { semacquire1(addr, false, semaBlockProfile, 0) } -//go:linkname sync_runtime_Semrelease sync.runtime_Semrelease +//go:linkname sync_runtime_Semrelease sync.runtime__Semrelease func sync_runtime_Semrelease(addr *uint32, handoff bool, skipframes int) { semrelease1(addr, handoff, skipframes) } -//go:linkname sync_runtime_SemacquireMutex sync.runtime_SemacquireMutex +//go:linkname sync_runtime_SemacquireMutex sync.runtime__SemacquireMutex func sync_runtime_SemacquireMutex(addr *uint32, lifo bool, skipframes int) { semacquire1(addr, lifo, semaBlockProfile|semaMutexProfile, skipframes) } -//go:linkname poll_runtime_Semrelease internal..z2fpoll.runtime_Semrelease +//go:linkname poll_runtime_Semrelease internal_1poll.runtime__Semrelease func poll_runtime_Semrelease(addr *uint32) { semrelease(addr) } @@ -475,7 +475,7 @@ func less(a, b uint32) bool { // notifyListAdd adds the caller to a notify list such that it can receive // notifications. The caller must eventually call notifyListWait to wait for // such a notification, passing the returned ticket number. -//go:linkname notifyListAdd sync.runtime_notifyListAdd +//go:linkname notifyListAdd sync.runtime__notifyListAdd func notifyListAdd(l *notifyList) uint32 { // This may be called concurrently, for example, when called from // sync.Cond.Wait while holding a RWMutex in read mode. @@ -484,7 +484,7 @@ func notifyListAdd(l *notifyList) uint32 { // notifyListWait waits for a notification. If one has been sent since // notifyListAdd was called, it returns immediately. Otherwise, it blocks. -//go:linkname notifyListWait sync.runtime_notifyListWait +//go:linkname notifyListWait sync.runtime__notifyListWait func notifyListWait(l *notifyList, t uint32) { lockWithRank(&l.lock, lockRankNotifyList) @@ -518,7 +518,7 @@ func notifyListWait(l *notifyList, t uint32) { } // notifyListNotifyAll notifies all entries in the list. -//go:linkname notifyListNotifyAll sync.runtime_notifyListNotifyAll +//go:linkname notifyListNotifyAll sync.runtime__notifyListNotifyAll func notifyListNotifyAll(l *notifyList) { // Fast-path: if there are no new waiters since the last notification // we don't need to acquire the lock. @@ -550,7 +550,7 @@ func notifyListNotifyAll(l *notifyList) { } // notifyListNotifyOne notifies one entry in the list. -//go:linkname notifyListNotifyOne sync.runtime_notifyListNotifyOne +//go:linkname notifyListNotifyOne sync.runtime__notifyListNotifyOne func notifyListNotifyOne(l *notifyList) { // Fast-path: if there are no new waiters since the last notification // we don't need to acquire the lock at all. @@ -603,7 +603,7 @@ func notifyListNotifyOne(l *notifyList) { unlock(&l.lock) } -//go:linkname notifyListCheck sync.runtime_notifyListCheck +//go:linkname notifyListCheck sync.runtime__notifyListCheck func notifyListCheck(sz uintptr) { if sz != unsafe.Sizeof(notifyList{}) { print("runtime: bad notifyList size - sync=", sz, " runtime=", unsafe.Sizeof(notifyList{}), "\n") @@ -611,7 +611,7 @@ func notifyListCheck(sz uintptr) { } } -//go:linkname sync_nanotime sync.runtime_nanotime +//go:linkname sync_nanotime sync.runtime__nanotime func sync_nanotime() int64 { return nanotime() } diff --git a/libgo/go/runtime/sigqueue.go b/libgo/go/runtime/sigqueue.go index 7d1028e..ed024e1 100644 --- a/libgo/go/runtime/sigqueue.go +++ b/libgo/go/runtime/sigqueue.go @@ -121,7 +121,7 @@ Send: // Called to receive the next queued signal. // Must only be called from a single goroutine at a time. -//go:linkname signal_recv os..z2fsignal.signal_recv +//go:linkname signal_recv os_1signal.signal__recv func signal_recv() uint32 { for { // Serve any signals from local copy. @@ -169,7 +169,7 @@ func signal_recv() uint32 { // the signal(s) in question, and here we are just waiting to make sure // that all the signals have been delivered to the user channels // by the os/signal package. -//go:linkname signalWaitUntilIdle os..z2fsignal.signalWaitUntilIdle +//go:linkname signalWaitUntilIdle os_1signal.signalWaitUntilIdle func signalWaitUntilIdle() { // Although the signals we care about have been removed from // sig.wanted, it is possible that another thread has received @@ -189,7 +189,7 @@ func signalWaitUntilIdle() { } // Must only be called from a single goroutine at a time. -//go:linkname signal_enable os..z2fsignal.signal_enable +//go:linkname signal_enable os_1signal.signal__enable func signal_enable(s uint32) { if !sig.inuse { // This is the first call to signal_enable. Initialize. @@ -217,7 +217,7 @@ func signal_enable(s uint32) { } // Must only be called from a single goroutine at a time. -//go:linkname signal_disable os..z2fsignal.signal_disable +//go:linkname signal_disable os_1signal.signal__disable func signal_disable(s uint32) { if s >= uint32(len(sig.wanted)*32) { return @@ -230,7 +230,7 @@ func signal_disable(s uint32) { } // Must only be called from a single goroutine at a time. -//go:linkname signal_ignore os..z2fsignal.signal_ignore +//go:linkname signal_ignore os_1signal.signal__ignore func signal_ignore(s uint32) { if s >= uint32(len(sig.wanted)*32) { return @@ -257,7 +257,7 @@ func sigInitIgnored(s uint32) { } // Checked by signal handlers. -//go:linkname signal_ignored os..z2fsignal.signal_ignored +//go:linkname signal_ignored os_1signal.signal__ignored func signal_ignored(s uint32) bool { i := atomic.Load(&sig.ignored[s/32]) return i&(1<<(s&31)) != 0 diff --git a/libgo/go/runtime/symtab.go b/libgo/go/runtime/symtab.go index bb0b61d..22a2b13 100644 --- a/libgo/go/runtime/symtab.go +++ b/libgo/go/runtime/symtab.go @@ -5,6 +5,7 @@ package runtime import ( + "internal/bytealg" _ "unsafe" // for go:linkname ) @@ -119,7 +120,7 @@ func pcInlineCallers(pc uintptr, locbuf *location, max int32) int32 // runtime_expandFinalInlineFrame expands the final pc in stk to include all // "callers" if pc is inline. // -//go:linkname runtime_expandFinalInlineFrame runtime..z2fpprof.runtime_expandFinalInlineFrame +//go:linkname runtime_expandFinalInlineFrame runtime_1pprof.runtime__expandFinalInlineFrame func runtime_expandFinalInlineFrame(stk []uintptr) []uintptr { if len(stk) == 0 { return stk @@ -210,42 +211,62 @@ func hexDigitsToRune(digits []byte, ndig int) rune { return rune(result) } -// Perform an in-place decoding on the input byte slice. This looks -// for "..z", "..u" and "..U" and overwrites -// with the encoded bytes corresponding to the unicode in question. -// Return value is the number of bytes taken by the result. - +// decodeIdentifier performs an in-place decoding on the input byte slice. +// This undoes the compiler underscore mangling. +// Returns the number of bytes used by the result. func decodeIdentifier(bsl []byte) int { + underscoreCodes := map[byte]byte{ + '_': '_', + '0': '.', + '1': '/', + '2': '*', + '3': ',', + '4': '{', + '5': '}', + '6': '[', + '7': ']', + '8': '(', + '9': ')', + 'a': '"', + 'b': ' ', + 'c': ';', + } + j := 0 for i := 0; i < len(bsl); i++ { b := bsl[i] + if b != '_' || i+1 >= len(bsl) { + bsl[j] = b + j++ + continue + } + + if d, ok := underscoreCodes[bsl[i+1]]; ok { + i++ + bsl[j] = d + j++ + continue + } + + rlen := 0 + switch bsl[i+1] { + case 'x': + rlen = 2 + case 'u': + rlen = 4 + case 'U': + rlen = 8 + } - if i+1 < len(bsl) && bsl[i] == '.' && bsl[i+1] == '.' { - if i+4 < len(bsl) && bsl[i+2] == 'z' { - digits := bsl[i+3:] - r := hexDigitsToRune(digits, 2) - nc := encoderune(bsl[j:], r) - j += nc - i += 4 - continue - } else if i+6 < len(bsl) && bsl[i+2] == 'u' { - digits := bsl[i+3:] - r := hexDigitsToRune(digits, 4) - nc := encoderune(bsl[j:], r) - j += nc - i += 6 - continue - } else if i+10 < len(bsl) && bsl[i+2] == 'U' { - digits := bsl[i+3:] - r := hexDigitsToRune(digits, 8) - nc := encoderune(bsl[j:], r) - j += nc - i += 10 - continue - } + if rlen > 0 && i+1+rlen < len(bsl) { + r := hexDigitsToRune(bsl[i+2:], rlen) + nc := encoderune(bsl[j:], r) + j += nc + i += rlen + 1 + } else { + bsl[j] = b + j++ } - bsl[j] = b - j += 1 } return j } @@ -254,6 +275,11 @@ func decodeIdentifier(bsl []byte) int { // as used in the compiler. func demangleSymbol(s string) string { + if bytealg.IndexByteString(s, '.') < 0 { + // A symbol with no '.' is not a Go symbol. + return s + } + bsl := []byte(s) nchars := decodeIdentifier(bsl) bsl = bsl[:nchars] diff --git a/libgo/go/runtime/trace.go b/libgo/go/runtime/trace.go index ce185fc..b05f30a 100644 --- a/libgo/go/runtime/trace.go +++ b/libgo/go/runtime/trace.go @@ -1152,7 +1152,7 @@ func traceNextGC() { // To access runtime functions from runtime/trace. // See runtime/trace/annotation.go -//go:linkname trace_userTaskCreate runtime..z2ftrace.userTaskCreate +//go:linkname trace_userTaskCreate runtime_1trace.userTaskCreate func trace_userTaskCreate(id, parentID uint64, taskType string) { if !trace.enabled { return @@ -1170,12 +1170,12 @@ func trace_userTaskCreate(id, parentID uint64, taskType string) { traceReleaseBuffer(pid) } -//go:linkname trace_userTaskEnd runtime..z2ftrace.userTaskEnd +//go:linkname trace_userTaskEnd runtime_1trace.userTaskEnd func trace_userTaskEnd(id uint64) { traceEvent(traceEvUserTaskEnd, 2, id) } -//go:linkname trace_userRegion runtime..z2ftrace.userRegion +//go:linkname trace_userRegion runtime_1trace.userRegion func trace_userRegion(id, mode uint64, name string) { if !trace.enabled { return @@ -1192,7 +1192,7 @@ func trace_userRegion(id, mode uint64, name string) { traceReleaseBuffer(pid) } -//go:linkname trace_userLog runtime..z2ftrace.userLog +//go:linkname trace_userLog runtime_1trace.userLog func trace_userLog(id uint64, category, message string) { if !trace.enabled { return diff --git a/libgo/go/runtime/traceback_gccgo.go b/libgo/go/runtime/traceback_gccgo.go index 1ba91af..ebdbefc 100644 --- a/libgo/go/runtime/traceback_gccgo.go +++ b/libgo/go/runtime/traceback_gccgo.go @@ -184,10 +184,10 @@ func showfuncinfo(name string, firstFrame bool) bool { // isExportedRuntime reports whether name is an exported runtime function. // It is only for runtime functions, so ASCII A-Z is fine. Here also check // for mangled functions from runtime/<...>, which will be prefixed with -// "runtime..z2f". +// "runtime_1". func isExportedRuntime(name string) bool { const n = len("runtime.") - if hasPrefix(name, "runtime..z2f") { + if hasPrefix(name, "runtime_1") { return true } return len(name) > n && name[:n] == "runtime." && 'A' <= name[n] && name[n] <= 'Z' diff --git a/libgo/go/sync/atomic/atomic.c b/libgo/go/sync/atomic/atomic.c index 90a4ff3..71d51aa 100644 --- a/libgo/go/sync/atomic/atomic.c +++ b/libgo/go/sync/atomic/atomic.c @@ -9,7 +9,7 @@ #include "runtime.h" int32_t SwapInt32 (int32_t *, int32_t) - __asm__ (GOSYM_PREFIX "sync..z2fatomic.SwapInt32") + __asm__ (GOSYM_PREFIX "sync_1atomic.SwapInt32") __attribute__ ((no_split_stack)); int32_t @@ -19,7 +19,7 @@ SwapInt32 (int32_t *addr, int32_t new) } int64_t SwapInt64 (int64_t *, int64_t) - __asm__ (GOSYM_PREFIX "sync..z2fatomic.SwapInt64") + __asm__ (GOSYM_PREFIX "sync_1atomic.SwapInt64") __attribute__ ((no_split_stack)); int64_t @@ -31,7 +31,7 @@ SwapInt64 (int64_t *addr, int64_t new) } uint32_t SwapUint32 (uint32_t *, uint32_t) - __asm__ (GOSYM_PREFIX "sync..z2fatomic.SwapUint32") + __asm__ (GOSYM_PREFIX "sync_1atomic.SwapUint32") __attribute__ ((no_split_stack)); uint32_t @@ -41,7 +41,7 @@ SwapUint32 (uint32_t *addr, uint32_t new) } uint64_t SwapUint64 (uint64_t *, uint64_t) - __asm__ (GOSYM_PREFIX "sync..z2fatomic.SwapUint64") + __asm__ (GOSYM_PREFIX "sync_1atomic.SwapUint64") __attribute__ ((no_split_stack)); uint64_t @@ -53,7 +53,7 @@ SwapUint64 (uint64_t *addr, uint64_t new) } uintptr_t SwapUintptr (uintptr_t *, uintptr_t) - __asm__ (GOSYM_PREFIX "sync..z2fatomic.SwapUintptr") + __asm__ (GOSYM_PREFIX "sync_1atomic.SwapUintptr") __attribute__ ((no_split_stack)); uintptr_t @@ -63,7 +63,7 @@ SwapUintptr (uintptr_t *addr, uintptr_t new) } _Bool CompareAndSwapInt32 (int32_t *, int32_t, int32_t) - __asm__ (GOSYM_PREFIX "sync..z2fatomic.CompareAndSwapInt32") + __asm__ (GOSYM_PREFIX "sync_1atomic.CompareAndSwapInt32") __attribute__ ((no_split_stack)); _Bool @@ -74,7 +74,7 @@ CompareAndSwapInt32 (int32_t *val, int32_t old, int32_t new) } _Bool CompareAndSwapInt64 (int64_t *, int64_t, int64_t) - __asm__ (GOSYM_PREFIX "sync..z2fatomic.CompareAndSwapInt64") + __asm__ (GOSYM_PREFIX "sync_1atomic.CompareAndSwapInt64") __attribute__ ((no_split_stack)); _Bool @@ -87,7 +87,7 @@ CompareAndSwapInt64 (int64_t *val, int64_t old, int64_t new) } _Bool CompareAndSwapUint32 (uint32_t *, uint32_t, uint32_t) - __asm__ (GOSYM_PREFIX "sync..z2fatomic.CompareAndSwapUint32") + __asm__ (GOSYM_PREFIX "sync_1atomic.CompareAndSwapUint32") __attribute__ ((no_split_stack)); _Bool @@ -98,7 +98,7 @@ CompareAndSwapUint32 (uint32_t *val, uint32_t old, uint32_t new) } _Bool CompareAndSwapUint64 (uint64_t *, uint64_t, uint64_t) - __asm__ (GOSYM_PREFIX "sync..z2fatomic.CompareAndSwapUint64") + __asm__ (GOSYM_PREFIX "sync_1atomic.CompareAndSwapUint64") __attribute__ ((no_split_stack)); _Bool @@ -111,7 +111,7 @@ CompareAndSwapUint64 (uint64_t *val, uint64_t old, uint64_t new) } _Bool CompareAndSwapUintptr (uintptr_t *, uintptr_t, uintptr_t) - __asm__ (GOSYM_PREFIX "sync..z2fatomic.CompareAndSwapUintptr") + __asm__ (GOSYM_PREFIX "sync_1atomic.CompareAndSwapUintptr") __attribute__ ((no_split_stack)); _Bool @@ -122,7 +122,7 @@ CompareAndSwapUintptr (uintptr_t *val, uintptr_t old, uintptr_t new) } int32_t AddInt32 (int32_t *, int32_t) - __asm__ (GOSYM_PREFIX "sync..z2fatomic.AddInt32") + __asm__ (GOSYM_PREFIX "sync_1atomic.AddInt32") __attribute__ ((no_split_stack)); int32_t @@ -132,7 +132,7 @@ AddInt32 (int32_t *val, int32_t delta) } uint32_t AddUint32 (uint32_t *, uint32_t) - __asm__ (GOSYM_PREFIX "sync..z2fatomic.AddUint32") + __asm__ (GOSYM_PREFIX "sync_1atomic.AddUint32") __attribute__ ((no_split_stack)); uint32_t @@ -142,7 +142,7 @@ AddUint32 (uint32_t *val, uint32_t delta) } int64_t AddInt64 (int64_t *, int64_t) - __asm__ (GOSYM_PREFIX "sync..z2fatomic.AddInt64") + __asm__ (GOSYM_PREFIX "sync_1atomic.AddInt64") __attribute__ ((no_split_stack)); int64_t @@ -154,7 +154,7 @@ AddInt64 (int64_t *val, int64_t delta) } uint64_t AddUint64 (uint64_t *, uint64_t) - __asm__ (GOSYM_PREFIX "sync..z2fatomic.AddUint64") + __asm__ (GOSYM_PREFIX "sync_1atomic.AddUint64") __attribute__ ((no_split_stack)); uint64_t @@ -166,7 +166,7 @@ AddUint64 (uint64_t *val, uint64_t delta) } uintptr_t AddUintptr (uintptr_t *, uintptr_t) - __asm__ (GOSYM_PREFIX "sync..z2fatomic.AddUintptr") + __asm__ (GOSYM_PREFIX "sync_1atomic.AddUintptr") __attribute__ ((no_split_stack)); uintptr_t @@ -176,7 +176,7 @@ AddUintptr (uintptr_t *val, uintptr_t delta) } int32_t LoadInt32 (int32_t *addr) - __asm__ (GOSYM_PREFIX "sync..z2fatomic.LoadInt32") + __asm__ (GOSYM_PREFIX "sync_1atomic.LoadInt32") __attribute__ ((no_split_stack)); int32_t @@ -186,7 +186,7 @@ LoadInt32 (int32_t *addr) } int64_t LoadInt64 (int64_t *addr) - __asm__ (GOSYM_PREFIX "sync..z2fatomic.LoadInt64") + __asm__ (GOSYM_PREFIX "sync_1atomic.LoadInt64") __attribute__ ((no_split_stack)); int64_t @@ -198,7 +198,7 @@ LoadInt64 (int64_t *addr) } uint32_t LoadUint32 (uint32_t *addr) - __asm__ (GOSYM_PREFIX "sync..z2fatomic.LoadUint32") + __asm__ (GOSYM_PREFIX "sync_1atomic.LoadUint32") __attribute__ ((no_split_stack)); uint32_t @@ -208,7 +208,7 @@ LoadUint32 (uint32_t *addr) } uint64_t LoadUint64 (uint64_t *addr) - __asm__ (GOSYM_PREFIX "sync..z2fatomic.LoadUint64") + __asm__ (GOSYM_PREFIX "sync_1atomic.LoadUint64") __attribute__ ((no_split_stack)); uint64_t @@ -220,7 +220,7 @@ LoadUint64 (uint64_t *addr) } uintptr_t LoadUintptr (uintptr_t *addr) - __asm__ (GOSYM_PREFIX "sync..z2fatomic.LoadUintptr") + __asm__ (GOSYM_PREFIX "sync_1atomic.LoadUintptr") __attribute__ ((no_split_stack)); uintptr_t @@ -230,7 +230,7 @@ LoadUintptr (uintptr_t *addr) } void *LoadPointer (void **addr) - __asm__ (GOSYM_PREFIX "sync..z2fatomic.LoadPointer") + __asm__ (GOSYM_PREFIX "sync_1atomic.LoadPointer") __attribute__ ((no_split_stack)); void * @@ -240,7 +240,7 @@ LoadPointer (void **addr) } void StoreInt32 (int32_t *addr, int32_t val) - __asm__ (GOSYM_PREFIX "sync..z2fatomic.StoreInt32") + __asm__ (GOSYM_PREFIX "sync_1atomic.StoreInt32") __attribute__ ((no_split_stack)); void @@ -250,7 +250,7 @@ StoreInt32 (int32_t *addr, int32_t val) } void StoreInt64 (int64_t *addr, int64_t val) - __asm__ (GOSYM_PREFIX "sync..z2fatomic.StoreInt64") + __asm__ (GOSYM_PREFIX "sync_1atomic.StoreInt64") __attribute__ ((no_split_stack)); void @@ -262,7 +262,7 @@ StoreInt64 (int64_t *addr, int64_t val) } void StoreUint32 (uint32_t *addr, uint32_t val) - __asm__ (GOSYM_PREFIX "sync..z2fatomic.StoreUint32") + __asm__ (GOSYM_PREFIX "sync_1atomic.StoreUint32") __attribute__ ((no_split_stack)); void @@ -272,7 +272,7 @@ StoreUint32 (uint32_t *addr, uint32_t val) } void StoreUint64 (uint64_t *addr, uint64_t val) - __asm__ (GOSYM_PREFIX "sync..z2fatomic.StoreUint64") + __asm__ (GOSYM_PREFIX "sync_1atomic.StoreUint64") __attribute__ ((no_split_stack)); void @@ -284,7 +284,7 @@ StoreUint64 (uint64_t *addr, uint64_t val) } void StoreUintptr (uintptr_t *addr, uintptr_t val) - __asm__ (GOSYM_PREFIX "sync..z2fatomic.StoreUintptr") + __asm__ (GOSYM_PREFIX "sync_1atomic.StoreUintptr") __attribute__ ((no_split_stack)); void -- cgit v1.1 From dec42fe4e3669409383d44d69a5992cd0c50fdb0 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Fri, 20 Nov 2020 15:19:29 -0800 Subject: libgo: update to Go 1.15.5 release Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/272146 --- libgo/go/cmd/cgo/out.go | 23 ++++++++++ libgo/go/cmd/go/internal/work/exec.go | 60 ++++++++++++++++++++++++++ libgo/go/cmd/go/internal/work/security.go | 8 ++-- libgo/go/cmd/go/internal/work/security_test.go | 5 +++ libgo/go/math/big/nat.go | 2 +- 5 files changed, 93 insertions(+), 5 deletions(-) (limited to 'libgo/go') diff --git a/libgo/go/cmd/cgo/out.go b/libgo/go/cmd/cgo/out.go index 0544139..1c143d7 100644 --- a/libgo/go/cmd/cgo/out.go +++ b/libgo/go/cmd/cgo/out.go @@ -341,6 +341,8 @@ func dynimport(obj string) { if s.Version != "" { targ += "#" + s.Version } + checkImportSymName(s.Name) + checkImportSymName(targ) fmt.Fprintf(stdout, "//go:cgo_import_dynamic %s %s %q\n", s.Name, targ, s.Library) } lib, _ := f.ImportedLibraries() @@ -356,6 +358,7 @@ func dynimport(obj string) { if len(s) > 0 && s[0] == '_' { s = s[1:] } + checkImportSymName(s) fmt.Fprintf(stdout, "//go:cgo_import_dynamic %s %s %q\n", s, s, "") } lib, _ := f.ImportedLibraries() @@ -370,6 +373,8 @@ func dynimport(obj string) { for _, s := range sym { ss := strings.Split(s, ":") name := strings.Split(ss[0], "@")[0] + checkImportSymName(name) + checkImportSymName(ss[0]) fmt.Fprintf(stdout, "//go:cgo_import_dynamic %s %s %q\n", name, ss[0], strings.ToLower(ss[1])) } return @@ -387,6 +392,7 @@ func dynimport(obj string) { // Go symbols. continue } + checkImportSymName(s.Name) fmt.Fprintf(stdout, "//go:cgo_import_dynamic %s %s %q\n", s.Name, s.Name, s.Library) } lib, err := f.ImportedLibraries() @@ -402,6 +408,23 @@ func dynimport(obj string) { fatalf("cannot parse %s as ELF, Mach-O, PE or XCOFF", obj) } +// checkImportSymName checks a symbol name we are going to emit as part +// of a //go:cgo_import_dynamic pragma. These names come from object +// files, so they may be corrupt. We are going to emit them unquoted, +// so while they don't need to be valid symbol names (and in some cases, +// involving symbol versions, they won't be) they must contain only +// graphic characters and must not contain Go comments. +func checkImportSymName(s string) { + for _, c := range s { + if !unicode.IsGraphic(c) || unicode.IsSpace(c) { + fatalf("dynamic symbol %q contains unsupported character", s) + } + } + if strings.Index(s, "//") >= 0 || strings.Index(s, "/*") >= 0 { + fatalf("dynamic symbol %q contains Go comment") + } +} + // Construct a gcc struct matching the gc argument frame. // Assumes that in gcc, char is 1 byte, short 2 bytes, int 4 bytes, long long 8 bytes. // These assumptions are checked by the gccProlog. diff --git a/libgo/go/cmd/go/internal/work/exec.go b/libgo/go/cmd/go/internal/work/exec.go index 65f3011..4f68943 100644 --- a/libgo/go/cmd/go/internal/work/exec.go +++ b/libgo/go/cmd/go/internal/work/exec.go @@ -2723,6 +2723,66 @@ func (b *Builder) cgo(a *Action, cgoExe, objdir string, pcCFLAGS, pcLDFLAGS, cgo noCompiler() } + // Double check the //go:cgo_ldflag comments in the generated files. + // The compiler only permits such comments in files whose base name + // starts with "_cgo_". Make sure that the comments in those files + // are safe. This is a backstop against people somehow smuggling + // such a comment into a file generated by cgo. + if cfg.BuildToolchainName == "gc" && !cfg.BuildN { + var flags []string + for _, f := range outGo { + if !strings.HasPrefix(filepath.Base(f), "_cgo_") { + continue + } + + src, err := ioutil.ReadFile(f) + if err != nil { + return nil, nil, err + } + + const cgoLdflag = "//go:cgo_ldflag" + idx := bytes.Index(src, []byte(cgoLdflag)) + for idx >= 0 { + // We are looking at //go:cgo_ldflag. + // Find start of line. + start := bytes.LastIndex(src[:idx], []byte("\n")) + if start == -1 { + start = 0 + } + + // Find end of line. + end := bytes.Index(src[idx:], []byte("\n")) + if end == -1 { + end = len(src) + } else { + end += idx + } + + // Check for first line comment in line. + // We don't worry about /* */ comments, + // which normally won't appear in files + // generated by cgo. + commentStart := bytes.Index(src[start:], []byte("//")) + commentStart += start + // If that line comment is //go:cgo_ldflag, + // it's a match. + if bytes.HasPrefix(src[commentStart:], []byte(cgoLdflag)) { + // Pull out the flag, and unquote it. + // This is what the compiler does. + flag := string(src[idx+len(cgoLdflag) : end]) + flag = strings.TrimSpace(flag) + flag = strings.Trim(flag, `"`) + flags = append(flags, flag) + } + src = src[end:] + idx = bytes.Index(src, []byte(cgoLdflag)) + } + } + if err := checkLinkerFlags("LDFLAGS", "go:cgo_ldflag", flags); err != nil { + return nil, nil, err + } + } + return outGo, outObj, nil } diff --git a/libgo/go/cmd/go/internal/work/security.go b/libgo/go/cmd/go/internal/work/security.go index 3ee68ac..0d96282 100644 --- a/libgo/go/cmd/go/internal/work/security.go +++ b/libgo/go/cmd/go/internal/work/security.go @@ -42,8 +42,8 @@ import ( var re = lazyregexp.New var validCompilerFlags = []*lazyregexp.Regexp{ - re(`-D([A-Za-z_].*)`), - re(`-U([A-Za-z_]*)`), + re(`-D([A-Za-z_][A-Za-z0-9_]*)(=[^@\-]*)?`), + re(`-U([A-Za-z_][A-Za-z0-9_]*)`), re(`-F([^@\-].*)`), re(`-I([^@\-].*)`), re(`-O`), @@ -51,8 +51,8 @@ var validCompilerFlags = []*lazyregexp.Regexp{ re(`-W`), re(`-W([^@,]+)`), // -Wall but not -Wa,-foo. re(`-Wa,-mbig-obj`), - re(`-Wp,-D([A-Za-z_].*)`), - re(`-Wp,-U([A-Za-z_]*)`), + re(`-Wp,-D([A-Za-z_][A-Za-z0-9_]*)(=[^@,\-]*)?`), + re(`-Wp,-U([A-Za-z_][A-Za-z0-9_]*)`), re(`-ansi`), re(`-f(no-)?asynchronous-unwind-tables`), re(`-f(no-)?blocks`), diff --git a/libgo/go/cmd/go/internal/work/security_test.go b/libgo/go/cmd/go/internal/work/security_test.go index 11e74f2..aec9789 100644 --- a/libgo/go/cmd/go/internal/work/security_test.go +++ b/libgo/go/cmd/go/internal/work/security_test.go @@ -13,6 +13,7 @@ var goodCompilerFlags = [][]string{ {"-DFOO"}, {"-Dfoo=bar"}, {"-Ufoo"}, + {"-Ufoo1"}, {"-F/Qt"}, {"-I/"}, {"-I/etc/passwd"}, @@ -24,6 +25,8 @@ var goodCompilerFlags = [][]string{ {"-Wall"}, {"-Wp,-Dfoo=bar"}, {"-Wp,-Ufoo"}, + {"-Wp,-Dfoo1"}, + {"-Wp,-Ufoo1"}, {"-fobjc-arc"}, {"-fno-objc-arc"}, {"-fomit-frame-pointer"}, @@ -78,6 +81,8 @@ var badCompilerFlags = [][]string{ {"-O@1"}, {"-Wa,-foo"}, {"-W@foo"}, + {"-Wp,-DX,-D@X"}, + {"-Wp,-UX,-U@X"}, {"-g@gdb"}, {"-g-gdb"}, {"-march=@dawn"}, diff --git a/libgo/go/math/big/nat.go b/libgo/go/math/big/nat.go index 6a3989b..8c43de6 100644 --- a/libgo/go/math/big/nat.go +++ b/libgo/go/math/big/nat.go @@ -928,7 +928,7 @@ func (z nat) divRecursiveStep(u, v nat, depth int, tmp *nat, temps []*nat) { // Now u < (v< Date: Sun, 22 Nov 2020 16:01:14 -0800 Subject: log/syslog: correct asm name for C function Patch from Rainer Orth. Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/272259 --- libgo/go/log/syslog/syslog_c.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'libgo/go') diff --git a/libgo/go/log/syslog/syslog_c.c b/libgo/go/log/syslog/syslog_c.c index 329df40..acfee6e 100644 --- a/libgo/go/log/syslog/syslog_c.c +++ b/libgo/go/log/syslog/syslog_c.c @@ -12,7 +12,7 @@ can't represent a C varargs function in Go. */ void syslog_c(intgo, const char*) - __asm__ (GOSYM_PREFIX "log_1syslog.syslog_c"); + __asm__ (GOSYM_PREFIX "log_1syslog.syslog__c"); void syslog_c (intgo priority, const char *msg) -- cgit v1.1 From 9ebad4b01c22d4c03a3552fd6b0e86c9de0ce6bd Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Sat, 28 Nov 2020 06:48:54 -0800 Subject: compiler, runtime: check len/cap for append(s, make(T, l)...) The overflow checks done in growslice always reported an error for the capacity argument, even if it was the length argument that overflowed. This change lets the code pass the current issue4085b.go test. Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/273806 --- libgo/go/runtime/slice.go | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'libgo/go') diff --git a/libgo/go/runtime/slice.go b/libgo/go/runtime/slice.go index 97b2659..ddd588e 100644 --- a/libgo/go/runtime/slice.go +++ b/libgo/go/runtime/slice.go @@ -15,6 +15,7 @@ import ( //go:linkname panicmakeslicelen //go:linkname panicmakeslicecap //go:linkname makeslice +//go:linkname checkMakeSlice //go:linkname makeslice64 //go:linkname growslice //go:linkname slicecopy @@ -91,6 +92,13 @@ func makeslicecopy(et *_type, tolen int, fromlen int, from unsafe.Pointer) unsaf } func makeslice(et *_type, len, cap int) unsafe.Pointer { + mem := checkMakeSlice(et, len, cap) + return mallocgc(mem, et, true) +} + +// checkMakeSlice is called for append(s, make([]T, len, cap)...) to check +// the values of len and cap. +func checkMakeSlice(et *_type, len, cap int) uintptr { mem, overflow := math.MulUintptr(et.size, uintptr(cap)) if overflow || mem > maxAlloc || len < 0 || len > cap { // NOTE: Produce a 'len out of range' error instead of a @@ -104,8 +112,7 @@ func makeslice(et *_type, len, cap int) unsafe.Pointer { } panicmakeslicecap() } - - return mallocgc(mem, et, true) + return mem } func makeslice64(et *_type, len64, cap64 int64) unsafe.Pointer { -- cgit v1.1 From eafb46ce90c23efd22c61d941face060bb9f11f3 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Sat, 28 Nov 2020 11:29:25 -0800 Subject: internal/cpu: don't define CacheLinePadSize for mips64x For libgo the definition comes from the generated file cpugen.go. Fixes PR go/98041 Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/273866 --- libgo/go/internal/cpu/cpu_mips64x.go | 2 -- 1 file changed, 2 deletions(-) (limited to 'libgo/go') diff --git a/libgo/go/internal/cpu/cpu_mips64x.go b/libgo/go/internal/cpu/cpu_mips64x.go index 0c4794a..af10a50 100644 --- a/libgo/go/internal/cpu/cpu_mips64x.go +++ b/libgo/go/internal/cpu/cpu_mips64x.go @@ -6,8 +6,6 @@ package cpu -const CacheLinePadSize = 32 - // This is initialized by archauxv and should not be changed after it is // initialized. var HWCap uint -- cgit v1.1