From 06e5529eceae35bb26b51f2430c2c9425149ede2 Mon Sep 17 00:00:00 2001 From: Jeremy Faller Date: Mon, 16 Sep 2019 11:32:35 -0400 Subject: [PATCH] cmd/link: prefix syms with "_" on darwin links RELNOTE=This change adds an underscore to all Go symbols in darwin, and the behavior might be confusing to users of tools like "nm", etc. Fixes #33808 Change-Id: I19ad626026ccae1e87b3bb97b6bb9fd55e95e121 Reviewed-on: https://go-review.googlesource.com/c/go/+/195619 Run-TryBot: Jeremy Faller TryBot-Result: Gobot Gobot Reviewed-by: Cherry Zhang --- src/cmd/link/internal/ld/issue33808_test.go | 53 +++++++++++++++++++++ src/cmd/link/internal/ld/macho.go | 5 +- src/debug/macho/file.go | 7 ++- 3 files changed, 62 insertions(+), 3 deletions(-) create mode 100644 src/cmd/link/internal/ld/issue33808_test.go diff --git a/src/cmd/link/internal/ld/issue33808_test.go b/src/cmd/link/internal/ld/issue33808_test.go new file mode 100644 index 0000000000..df928a73d6 --- /dev/null +++ b/src/cmd/link/internal/ld/issue33808_test.go @@ -0,0 +1,53 @@ +// Copyright 2019 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 ld + +import ( + "internal/testenv" + "io/ioutil" + "os" + "runtime" + "strings" + "testing" +) + +const prog = ` +package main + +import "log" + +func main() { + log.Fatalf("HERE") +} +` + +func TestIssue33808(t *testing.T) { + if runtime.GOOS != "darwin" { + return + } + testenv.MustHaveGoBuild(t) + + dir, err := ioutil.TempDir("", "TestIssue33808") + if err != nil { + t.Fatalf("could not create directory: %v", err) + } + defer os.RemoveAll(dir) + + f := gobuild(t, dir, prog, "-ldflags=-linkmode=external") + f.Close() + + syms, err := f.Symbols() + if err != nil { + t.Fatalf("Error reading symbols: %v", err) + } + + name := "log.Fatalf" + for _, sym := range syms { + if strings.Contains(sym.Name, name) { + return + } + } + t.Fatalf("Didn't find %v", name) +} diff --git a/src/cmd/link/internal/ld/macho.go b/src/cmd/link/internal/ld/macho.go index 02e133e31d..7453f37c62 100644 --- a/src/cmd/link/internal/ld/macho.go +++ b/src/cmd/link/internal/ld/macho.go @@ -869,6 +869,7 @@ func machosymtab(ctxt *Link) { symtab.AddUint32(ctxt.Arch, uint32(symstr.Size)) export := machoShouldExport(ctxt, s) + isGoSymbol := strings.Contains(s.Extname(), ".") // In normal buildmodes, only add _ to C symbols, as // Go symbols have dot in the name. @@ -877,8 +878,8 @@ func machosymtab(ctxt *Link) { // symbols like crosscall2 are in pclntab and end up // pointing at the host binary, breaking unwinding. // See Issue #18190. - cexport := !strings.Contains(s.Extname(), ".") && (ctxt.BuildMode != BuildModePlugin || onlycsymbol(s)) - if cexport || export { + cexport := !isGoSymbol && (ctxt.BuildMode != BuildModePlugin || onlycsymbol(s)) + if cexport || export || isGoSymbol { symstr.AddUint8('_') } diff --git a/src/debug/macho/file.go b/src/debug/macho/file.go index 16708e5247..085b0c8219 100644 --- a/src/debug/macho/file.go +++ b/src/debug/macho/file.go @@ -473,7 +473,12 @@ func (f *File) parseSymtab(symdat, strtab, cmddat []byte, hdr *SymtabCmd, offset if n.Name >= uint32(len(strtab)) { return nil, &FormatError{offset, "invalid name in symbol table", n.Name} } - sym.Name = cstring(strtab[n.Name:]) + // We add "_" to Go symbols. Strip it here. See issue 33808. + name := cstring(strtab[n.Name:]) + if strings.Contains(name, ".") && name[0] == '_' { + name = name[1:] + } + sym.Name = name sym.Type = n.Type sym.Sect = n.Sect sym.Desc = n.Desc