--- /dev/null
+// 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)
+ testenv.MustHaveCGO(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)
+}
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.
// 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('_')
}
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