]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile, runtime: make the go.itab.* symbols module-local
authorMichael Hudson-Doyle <michael.hudson@canonical.com>
Wed, 26 Oct 2016 02:57:58 +0000 (15:57 +1300)
committerMichael Hudson-Doyle <michael.hudson@canonical.com>
Thu, 27 Oct 2016 19:13:35 +0000 (19:13 +0000)
Otherwise, the way the ELF dynamic linker works means that you can end up with
the same itab being passed to additab twice, leading to the itab linked list
having a cycle in it. Add a test to additab in runtime to catch this when it
happens, not some arbitrary and surprsing time later.

Fixes #17594

Change-Id: I6c82edcc9ac88ac188d1185370242dc92f46b1ad
Reviewed-on: https://go-review.googlesource.com/32131
Run-TryBot: Michael Hudson-Doyle <michael.hudson@canonical.com>
Reviewed-by: David Crawshaw <crawshaw@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>

misc/cgo/testshared/src/depBase/dep.go
misc/cgo/testshared/src/exe/exe.go
src/cmd/compile/internal/gc/reflect.go
src/runtime/iface.go

index c3ae96fe98278072f4c0356e617c91d8c12e5314..a518b4efe2955e785b7c46fddf9513bf89902624 100644 (file)
@@ -1,5 +1,10 @@
 package depBase
 
+import (
+       "os"
+       "reflect"
+)
+
 var V int = 1
 
 var HasMask []string = []string{"hi"}
@@ -13,6 +18,10 @@ type Dep struct {
 }
 
 func (d *Dep) Method() int {
+       // This code below causes various go.itab.* symbols to be generated in
+       // the shared library. Similar code in ../exe/exe.go results in
+       // exercising https://github.com/golang/go/issues/17594
+       reflect.TypeOf(os.Stdout).Elem()
        return 10
 }
 
index 136803fbc1d496f4cffb788b7773a6cd62a217ab..31fbedd31c55826162940883cb457ec4f05e4ab7 100644 (file)
@@ -2,11 +2,17 @@ package main
 
 import (
        "depBase"
+       "os"
+       "reflect"
        "runtime"
 )
 
 func main() {
        defer depBase.ImplementedInAsm()
+       // This code below causes various go.itab.* symbols to be generated in
+       // the executable. Similar code in ../depBase/dep.go results in
+       // exercising https://github.com/golang/go/issues/17594
+       reflect.TypeOf(os.Stdout).Elem()
        runtime.GC()
        depBase.V = depBase.F() + 1
 }
index da63f87c22e4f130c4cc05073d886773523968f0..57192dec1cd9a2e282d1ea471251c385286d6704 100644 (file)
@@ -1395,11 +1395,11 @@ func dumptypestructs() {
                o += len(imethods(i.itype)) * Widthptr // skip fun method pointers
                // at runtime the itab will contain pointers to types, other itabs and
                // method functions. None are allocated on heap, so we can use obj.NOPTR.
-               ggloblsym(i.sym, int32(o), int16(obj.DUPOK|obj.NOPTR))
+               ggloblsym(i.sym, int32(o), int16(obj.DUPOK|obj.NOPTR|obj.LOCAL))
 
                ilink := Pkglookup(i.t.tconv(FmtLeft)+","+i.itype.tconv(FmtLeft), itablinkpkg)
                dsymptr(ilink, 0, i.sym, 0)
-               ggloblsym(ilink, int32(Widthptr), int16(obj.DUPOK|obj.RODATA))
+               ggloblsym(ilink, int32(Widthptr), int16(obj.DUPOK|obj.RODATA|obj.LOCAL))
        }
 
        // process ptabs
index b55a9ed893179055883303eff386ffb38a578fa2..f7ad40d1c024b734056b70e15a52d40d77618208 100644 (file)
@@ -138,6 +138,10 @@ func additab(m *itab, locked, canfail bool) {
                throw("invalid itab locking")
        }
        h := itabhash(inter, typ)
+       if m == hash[h] {
+               println("duplicate itab for", typ.string(), "and", inter.typ.string())
+               throw("duplicate itabs")
+       }
        m.link = hash[h]
        atomicstorep(unsafe.Pointer(&hash[h]), unsafe.Pointer(m))
 }