externs := len(externdcl)
dumpglobls()
+ dumpptabs()
dumptypestructs()
// Dump extra globals.
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 {
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
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