// Copyright 2022 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 ir import ( "cmd/compile/internal/base" "cmd/internal/obj" ) // 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. // For body-less functions, we only create the LSym; for functions // with bodies call a helper to setup up / populate the LSym. func InitLSym(f *Func, hasBody bool) { if f.LSym != nil { base.FatalfAt(f.Pos(), "InitLSym called twice on %v", f) } if nam := f.Nname; !IsBlank(nam) { f.LSym = nam.LinksymABI(f.ABI) if f.Pragma&Systemstack != 0 { f.LSym.Set(obj.AttrCFunc, true) } } if hasBody { setupTextLSym(f, 0) } } // setupTextLSym initializes the LSym for a with-body text symbol. func setupTextLSym(f *Func, flag int) { if f.Dupok() { flag |= obj.DUPOK } if f.Wrapper() { flag |= obj.WRAPPER } if f.ABIWrapper() { flag |= obj.ABIWRAPPER } if f.Needctxt() { flag |= obj.NEEDCTXT } if f.Pragma&Nosplit != 0 { flag |= obj.NOSPLIT } if f.IsPackageInit() { flag |= obj.PKGINIT } // Clumsy but important. // For functions that could be on the path of invoking a deferred // function that can recover (runtime.reflectcall, reflect.callReflect, // and reflect.callMethod), we want the panic+recover special handling. // See test/recover.go for test cases and src/reflect/value.go // for the actual functions being considered. // // runtime.reflectcall is an assembly function which tailcalls // WRAPPER functions (runtime.callNN). Its ABI wrapper needs WRAPPER // flag as well. fnname := f.Sym().Name if base.Ctxt.Pkgpath == "runtime" && fnname == "reflectcall" { flag |= obj.WRAPPER } else if base.Ctxt.Pkgpath == "reflect" { switch fnname { case "callReflect", "callMethod": flag |= obj.WRAPPER } } base.Ctxt.InitTextSym(f.LSym, flag, f.Pos()) }