]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: generate table of main symbol types
authorDavid Crawshaw <crawshaw@golang.org>
Fri, 26 Aug 2016 00:29:15 +0000 (20:29 -0400)
committerDavid Crawshaw <crawshaw@golang.org>
Tue, 6 Sep 2016 17:03:38 +0000 (17:03 +0000)
For each exported symbol in package main, add its name and type to
go.plugin.tabs symbol. This is used by the runtime when loading a
plugin to return a typed interface{} value.

Change-Id: I23c39583e57180acb8f7a74d218dae4368614f46
Reviewed-on: https://go-review.googlesource.com/27818
Run-TryBot: David Crawshaw <crawshaw@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
src/cmd/compile/internal/gc/obj.go
src/cmd/compile/internal/gc/reflect.go

index ed69c7a6772d0ec083b826ff946ff7de1ced29b0..4748bcb8b63197c53848bc7920033f27c2d8d056 100644 (file)
@@ -130,6 +130,7 @@ func dumpobj1(outfile string, mode int) {
        externs := len(externdcl)
 
        dumpglobls()
+       dumpptabs()
        dumptypestructs()
 
        // Dump extra globals.
@@ -163,6 +164,35 @@ func dumpobj1(outfile string, mode int) {
        bout.Close()
 }
 
+func dumpptabs() {
+       if !Ctxt.Flag_dynlink || localpkg.Name != "main" {
+               return
+       }
+       for _, exportn := range exportlist {
+               s := exportn.Sym
+               n := s.Def
+               if n == nil {
+                       continue
+               }
+               if n.Op != ONAME {
+                       continue
+               }
+               if !exportname(s.Name) {
+                       continue
+               }
+               if s.Pkg.Name != "main" {
+                       continue
+               }
+               if n.Type.Etype == TFUNC && n.Class == PFUNC {
+                       // function
+                       ptabs = append(ptabs, ptabEntry{s: s, t: s.Def.Type})
+               } else {
+                       // variable
+                       ptabs = append(ptabs, ptabEntry{s: s, t: typPtr(s.Def.Type)})
+               }
+       }
+}
+
 func dumpglobls() {
        // add globals
        for _, n := range externdcl {
index 4a396d293ad1c5a07e287514d6859dacb54aba01..31be43d8c37212827a0da2028f1451dfe26933de 100644 (file)
@@ -18,9 +18,15 @@ type itabEntry struct {
        sym      *Sym
 }
 
+type ptabEntry struct {
+       s *Sym
+       t *Type
+}
+
 // runtime interface and reflection data structures
 var signatlist []*Node
 var itabs []itabEntry
+var ptabs []ptabEntry
 
 type Sig struct {
        name   string
@@ -1405,6 +1411,31 @@ func dumptypestructs() {
                ggloblsym(ilink, int32(Widthptr), int16(obj.DUPOK|obj.RODATA))
        }
 
+       // process ptabs
+       if localpkg.Name == "main" && len(ptabs) > 0 {
+               ot := 0
+               s := obj.Linklookup(Ctxt, "go.plugin.tabs", 0)
+               for _, p := range ptabs {
+                       // Dump ptab symbol into go.pluginsym package.
+                       //
+                       // type ptab struct {
+                       //      name nameOff
+                       //      typ  typeOff // pointer to symbol
+                       // }
+                       nsym := dname(p.s.Name, "", nil, true)
+                       ot = dsymptrOffLSym(s, ot, nsym, 0)
+                       ot = dsymptrOffLSym(s, ot, Linksym(typesym(p.t)), 0)
+               }
+               ggloblLSym(s, int32(ot), int16(obj.RODATA))
+
+               ot = 0
+               s = obj.Linklookup(Ctxt, "go.plugin.exports", 0)
+               for _, p := range ptabs {
+                       ot = dsymptrLSym(s, ot, Linksym(p.s), 0)
+               }
+               ggloblLSym(s, int32(ot), int16(obj.RODATA))
+       }
+
        // generate import strings for imported packages
        if forceObjFileStability {
                // Sorting the packages is not necessary but to compare binaries created