summaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/gc/gsubr.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/compile/internal/gc/gsubr.go')
-rw-r--r--src/cmd/compile/internal/gc/gsubr.go63
1 files changed, 62 insertions, 1 deletions
diff --git a/src/cmd/compile/internal/gc/gsubr.go b/src/cmd/compile/internal/gc/gsubr.go
index 16602b9988..01ac4cb929 100644
--- a/src/cmd/compile/internal/gc/gsubr.go
+++ b/src/cmd/compile/internal/gc/gsubr.go
@@ -187,7 +187,13 @@ func (pp *Progs) settext(fn *Node) {
ptxt.From.Sym = fn.Func.lsym
}
-func (f *Func) initLSym() {
+// initLSym defines f's obj.LSym and initializes it based on the
+// properties of f. This includes setting the symbol flags and ABI and
+// creating and initializing related DWARF symbols.
+//
+// initLSym must be called exactly once per function and must be
+// called for both functions with bodies and functions without bodies.
+func (f *Func) initLSym(hasBody bool) {
if f.lsym != nil {
Fatalf("Func.initLSym called twice")
}
@@ -197,6 +203,61 @@ func (f *Func) initLSym() {
if f.Pragma&Systemstack != 0 {
f.lsym.Set(obj.AttrCFunc, true)
}
+
+ var aliasABI obj.ABI
+ needABIAlias := false
+ if abi, ok := symabiDefs[f.lsym.Name]; ok && abi == obj.ABI0 {
+ // Symbol is defined as ABI0. Create an
+ // Internal -> ABI0 wrapper.
+ f.lsym.SetABI(obj.ABI0)
+ needABIAlias, aliasABI = true, obj.ABIInternal
+ } else {
+ // No ABI override. Check that the symbol is
+ // using the expected ABI.
+ want := obj.ABIInternal
+ if f.lsym.ABI() != want {
+ Fatalf("function symbol %s has the wrong ABI %v, expected %v", f.lsym, f.lsym.ABI(), want)
+ }
+ }
+
+ if abi, ok := symabiRefs[f.lsym.Name]; ok && abi == obj.ABI0 {
+ // Symbol is referenced as ABI0. Create an
+ // ABI0 -> Internal wrapper if necessary.
+ if f.lsym.ABI() != obj.ABI0 {
+ needABIAlias, aliasABI = true, obj.ABI0
+ }
+ }
+
+ if !needABIAlias && allABIs {
+ // The compiler was asked to produce ABI
+ // wrappers for everything.
+ switch f.lsym.ABI() {
+ case obj.ABI0:
+ needABIAlias, aliasABI = true, obj.ABIInternal
+ case obj.ABIInternal:
+ needABIAlias, aliasABI = true, obj.ABI0
+ }
+ }
+
+ if needABIAlias {
+ // These LSyms have the same name as the
+ // native function, so we create them directly
+ // rather than looking them up. The uniqueness
+ // of f.lsym ensures uniqueness of asym.
+ asym := &obj.LSym{
+ Name: f.lsym.Name,
+ Type: objabi.SABIALIAS,
+ R: []obj.Reloc{{Sym: f.lsym}}, // 0 size, so "informational"
+ }
+ asym.SetABI(aliasABI)
+ asym.Set(obj.AttrDuplicateOK, true)
+ Ctxt.ABIAliases = append(Ctxt.ABIAliases, asym)
+ }
+ }
+
+ if !hasBody {
+ // For body-less functions, we only create the LSym.
+ return
}
var flag int