]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/link: limit darwin dynlink symbol exports
authorDavid Crawshaw <crawshaw@golang.org>
Fri, 9 Dec 2016 17:38:34 +0000 (12:38 -0500)
committerDavid Crawshaw <crawshaw@golang.org>
Sat, 10 Dec 2016 17:03:45 +0000 (17:03 +0000)
The pclntable contains pointers to functions. If the function symbol
is exported in a plugin, and there is a matching symbol in the host
binary, then the pclntable of a plugin ends up pointing at the
function in the host module.

This doesn't work because the traceback code expects the pointer to
be in the same module space as the PC value.

So don't export functions that might overlap with the host binary.
This way the pointer stays in its module.

Updates #18190

Change-Id: Ifb77605b35fb0a1e7edeecfd22b1e335ed4bb392
Reviewed-on: https://go-review.googlesource.com/34196
Run-TryBot: David Crawshaw <crawshaw@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
misc/cgo/testplugin/src/plugin1/plugin1.go
src/cmd/link/internal/ld/macho.go

index 7a62242134338e63a3b3e408b17b769425f900bb..edcef2c77e9167fa6548b534bafc0d9dc2c4a319 100644 (file)
@@ -9,7 +9,10 @@ import "C"
 
 import "common"
 
-func F() int { return 3 }
+func F() int {
+       _ = make([]byte, 1<<21) // trigger stack unwind, Issue #18190.
+       return 3
+}
 
 func ReadCommonX() int {
        return common.X
index c88af64a3ac2a5a034f07fdb46df92ad1269142c..ff5fe5747b2d7c836f2676d052736c1727dfe819 100644 (file)
@@ -684,6 +684,20 @@ func machosymorder(ctxt *Link) {
        }
 }
 
+// machoShouldExport reports whether a symbol needs to be exported.
+//
+// When dynamically linking, all non-local variables and plugin-exported
+// symbols need to be exported.
+func machoShouldExport(ctxt *Link, s *Symbol) bool {
+       if !ctxt.DynlinkingGo() || s.Attr.Local() {
+               return false
+       }
+       if Buildmode == BuildmodePlugin && strings.HasPrefix(s.Extname, *flagPluginPath) {
+               return true
+       }
+       return s.Type != obj.STEXT
+}
+
 func machosymtab(ctxt *Link) {
        symtab := ctxt.Syms.Lookup(".machosymtab", 0)
        symstr := ctxt.Syms.Lookup(".machosymstr", 0)
@@ -692,13 +706,11 @@ func machosymtab(ctxt *Link) {
                s := sortsym[i]
                Adduint32(ctxt, symtab, uint32(symstr.Size))
 
+               export := machoShouldExport(ctxt, s)
+
                // In normal buildmodes, only add _ to C symbols, as
                // Go symbols have dot in the name.
-               //
-               // When dynamically linking, prefix all non-local
-               // symbols with _ as dlsym on darwin requires it to
-               // resolve any symbol.
-               if !strings.Contains(s.Extname, ".") || (ctxt.DynlinkingGo() && !s.Attr.Local()) {
+               if !strings.Contains(s.Extname, ".") || export {
                        Adduint8(ctxt, symstr, '_')
                }
 
@@ -711,7 +723,7 @@ func machosymtab(ctxt *Link) {
                        Adduint16(ctxt, symtab, 0)                  // desc
                        adduintxx(ctxt, symtab, 0, SysArch.PtrSize) // no value
                } else {
-                       if s.Attr.CgoExport() || (ctxt.DynlinkingGo() && !s.Attr.Local()) {
+                       if s.Attr.CgoExport() || export {
                                Adduint8(ctxt, symtab, 0x0f)
                        } else {
                                Adduint8(ctxt, symtab, 0x0e)