errorexit()
}
- // The "init" function is the only user-spellable symbol that
- // we construct later. Mark it as a function now before
- // anything can ask for its Linksym.
- lookup("init").SetFunc(true)
-
// Phase 4: Decide how to capture closed variables.
// This needs to run before escape analysis,
// because variables captured by value do not escape.
WasmDiv = sysvar("wasmDiv")
WasmTruncS = sysvar("wasmTruncS")
WasmTruncU = sysvar("wasmTruncU")
- SigPanic = sysvar("sigpanic")
+ SigPanic = sysfunc("sigpanic")
}
// buildssa builds an SSA function for fn.
}
if sym.Func() {
// This is a function symbol. Mark it as "internal ABI".
- return Ctxt.LookupInit(sym.LinksymName(), func(s *obj.LSym) {
- s.SetABI(obj.ABIInternal)
- })
+ return Ctxt.LookupABI(sym.LinksymName(), obj.ABIInternal)
}
return Ctxt.Lookup(sym.LinksymName())
}
return
}
- deferreturn = ctxt.Lookup("runtime.deferreturn")
- deferreturn.SetABI(obj.ABIInternal)
+ deferreturn = ctxt.LookupABI("runtime.deferreturn", obj.ABIInternal)
symdiv = ctxt.Lookup("runtime._div")
symdivu = ctxt.Lookup("runtime._divu")
Flag_locationlists bool
Bso *bufio.Writer
Pathname string
- hashmu sync.Mutex // protects hash
+ hashmu sync.Mutex // protects hash, funchash
hash map[string]*LSym // name -> sym mapping
+ funchash map[string]*LSym // name -> sym mapping for ABIInternal syms
statichash map[string]*LSym // name -> sym mapping for static syms
PosTable src.PosTable
InlTree InlTree // global inlining tree used by gc/inl.go
func Linknew(arch *LinkArch) *Link {
ctxt := new(Link)
ctxt.hash = make(map[string]*LSym)
+ ctxt.funchash = make(map[string]*LSym)
ctxt.statichash = make(map[string]*LSym)
ctxt.Arch = arch
ctxt.Pathname = objabi.WorkingDir()
return s
}
+// LookupABI looks up a symbol with the given ABI.
+// If it does not exist, it creates it.
+func (ctxt *Link) LookupABI(name string, abi ABI) *LSym {
+ var hash map[string]*LSym
+ switch abi {
+ case ABI0:
+ hash = ctxt.hash
+ case ABIInternal:
+ hash = ctxt.funchash
+ default:
+ panic("unknown ABI")
+ }
+
+ ctxt.hashmu.Lock()
+ s := hash[name]
+ if s == nil {
+ s = &LSym{Name: name}
+ s.SetABI(abi)
+ hash[name] = s
+ }
+ ctxt.hashmu.Unlock()
+ return s
+}
+
// Lookup looks up the symbol with name name.
// If it does not exist, it creates it.
func (ctxt *Link) Lookup(name string) *LSym {
morestack = ctxt.Lookup("runtime.morestack")
morestackNoCtxt = ctxt.Lookup("runtime.morestack_noctxt")
gcWriteBarrier = ctxt.Lookup("runtime.gcWriteBarrier")
- sigpanic = ctxt.Lookup("runtime.sigpanic")
- sigpanic.SetABI(obj.ABIInternal)
- deferreturn = ctxt.Lookup("runtime.deferreturn")
- deferreturn.SetABI(obj.ABIInternal)
- jmpdefer = ctxt.Lookup(`"".jmpdefer`)
+ sigpanic = ctxt.LookupABI("runtime.sigpanic", obj.ABIInternal)
+ deferreturn = ctxt.LookupABI("runtime.deferreturn", obj.ABIInternal)
+ // jmpdefer is defined in assembly as ABI0, but what we're
+ // looking for is the *call* to jmpdefer from the Go function
+ // deferreturn, so we're looking for the ABIInternal version
+ // of jmpdefer that's called by Go.
+ jmpdefer = ctxt.LookupABI(`"".jmpdefer`, obj.ABIInternal)
}
func preprocess(ctxt *obj.Link, s *obj.LSym, newprog obj.ProgAlloc) {
case objabi.Hplan9:
plan9privates = ctxt.Lookup("_privates")
case objabi.Hnacl:
- deferreturn = ctxt.Lookup("runtime.deferreturn")
- deferreturn.SetABI(obj.ABIInternal)
+ deferreturn = ctxt.LookupABI("runtime.deferreturn", obj.ABIInternal)
}
for i := range avxOptab {
--- /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 a
+
+type I interface {
+ M(init bool)
+}
+
+var V I
+
+func init() {
+ V = nil
+}
--- /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 b
+
+import "./a"
+
+type S struct {
+ a.I
+}
+
+var V a.I
+
+func init() {
+ V = S{}
+}
--- /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 main
+
+import "./b"
+
+var v b.S
+
+func main() {}
--- /dev/null
+// rundir
+
+// Copyright 2018 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.
+
+// Issue 29610: Symbol import and initialization order caused function
+// symbols to be recorded as non-function symbols.
+
+// This uses rundir not because we actually want to run the final
+// binary, but because we need to at least link it.
+
+package ignored