mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
cmd/internal/obj: flag init functions in object file
Introduce a flag in the object file indicating whether a given function corresponds to a compiler-generated (not user-written) init function, such as "os.init" or "syscall.init". Add code to the compiler to fill in the correct value for the flag, and add support to the loader package in the linker for testing the flag. The new loader API is currently unused, but will be needed in the next CL in this stack. Updates #2559. Updates #36021. Updates #14840. Change-Id: Iea7ad2adda487e4af7a44f062f9817977c53b394 Reviewed-on: https://go-review.googlesource.com/c/go/+/463855 Reviewed-by: Cherry Mui <cherryyz@google.com> Run-TryBot: Than McIntosh <thanm@google.com> TryBot-Result: Gopher Robot <gobot@golang.org>
This commit is contained in:
parent
8fd6cc8bb5
commit
55bd193575
9 changed files with 30 additions and 0 deletions
|
|
@ -53,6 +53,9 @@ func setupTextLSym(f *Func, flag int) {
|
||||||
if f.ReflectMethod() {
|
if f.ReflectMethod() {
|
||||||
flag |= obj.REFLECTMETHOD
|
flag |= obj.REFLECTMETHOD
|
||||||
}
|
}
|
||||||
|
if f.IsPackageInit() {
|
||||||
|
flag |= obj.PKGINIT
|
||||||
|
}
|
||||||
|
|
||||||
// Clumsy but important.
|
// Clumsy but important.
|
||||||
// For functions that could be on the path of invoking a deferred
|
// For functions that could be on the path of invoking a deferred
|
||||||
|
|
|
||||||
|
|
@ -204,6 +204,7 @@ const (
|
||||||
funcInstrumentBody // add race/msan/asan instrumentation during SSA construction
|
funcInstrumentBody // add race/msan/asan instrumentation during SSA construction
|
||||||
funcOpenCodedDeferDisallowed // can't do open-coded defers
|
funcOpenCodedDeferDisallowed // can't do open-coded defers
|
||||||
funcClosureCalled // closure is only immediately called; used by escape analysis
|
funcClosureCalled // closure is only immediately called; used by escape analysis
|
||||||
|
funcPackageInit // compiler emitted .init func for package
|
||||||
)
|
)
|
||||||
|
|
||||||
type SymAndPos struct {
|
type SymAndPos struct {
|
||||||
|
|
@ -225,6 +226,7 @@ func (f *Func) ExportInline() bool { return f.flags&funcExportInline
|
||||||
func (f *Func) InstrumentBody() bool { return f.flags&funcInstrumentBody != 0 }
|
func (f *Func) InstrumentBody() bool { return f.flags&funcInstrumentBody != 0 }
|
||||||
func (f *Func) OpenCodedDeferDisallowed() bool { return f.flags&funcOpenCodedDeferDisallowed != 0 }
|
func (f *Func) OpenCodedDeferDisallowed() bool { return f.flags&funcOpenCodedDeferDisallowed != 0 }
|
||||||
func (f *Func) ClosureCalled() bool { return f.flags&funcClosureCalled != 0 }
|
func (f *Func) ClosureCalled() bool { return f.flags&funcClosureCalled != 0 }
|
||||||
|
func (f *Func) IsPackageInit() bool { return f.flags&funcPackageInit != 0 }
|
||||||
|
|
||||||
func (f *Func) SetDupok(b bool) { f.flags.set(funcDupok, b) }
|
func (f *Func) SetDupok(b bool) { f.flags.set(funcDupok, b) }
|
||||||
func (f *Func) SetWrapper(b bool) { f.flags.set(funcWrapper, b) }
|
func (f *Func) SetWrapper(b bool) { f.flags.set(funcWrapper, b) }
|
||||||
|
|
@ -240,6 +242,7 @@ func (f *Func) SetExportInline(b bool) { f.flags.set(funcExportInlin
|
||||||
func (f *Func) SetInstrumentBody(b bool) { f.flags.set(funcInstrumentBody, b) }
|
func (f *Func) SetInstrumentBody(b bool) { f.flags.set(funcInstrumentBody, b) }
|
||||||
func (f *Func) SetOpenCodedDeferDisallowed(b bool) { f.flags.set(funcOpenCodedDeferDisallowed, b) }
|
func (f *Func) SetOpenCodedDeferDisallowed(b bool) { f.flags.set(funcOpenCodedDeferDisallowed, b) }
|
||||||
func (f *Func) SetClosureCalled(b bool) { f.flags.set(funcClosureCalled, b) }
|
func (f *Func) SetClosureCalled(b bool) { f.flags.set(funcClosureCalled, b) }
|
||||||
|
func (f *Func) SetIsPackageInit(b bool) { f.flags.set(funcPackageInit, b) }
|
||||||
|
|
||||||
func (f *Func) SetWBPos(pos src.XPos) {
|
func (f *Func) SetWBPos(pos src.XPos) {
|
||||||
if base.Debug.WB != 0 {
|
if base.Debug.WB != 0 {
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,7 @@ func MakeInit() {
|
||||||
}
|
}
|
||||||
fn.Dcl = append(fn.Dcl, typecheck.InitTodoFunc.Dcl...)
|
fn.Dcl = append(fn.Dcl, typecheck.InitTodoFunc.Dcl...)
|
||||||
typecheck.InitTodoFunc.Dcl = nil
|
typecheck.InitTodoFunc.Dcl = nil
|
||||||
|
fn.SetIsPackageInit(true)
|
||||||
|
|
||||||
// Suppress useless "can inline" diagnostics.
|
// Suppress useless "can inline" diagnostics.
|
||||||
// Init functions are only called dynamically.
|
// Init functions are only called dynamically.
|
||||||
|
|
|
||||||
|
|
@ -303,6 +303,7 @@ const (
|
||||||
SymFlagUsedInIface = 1 << iota
|
SymFlagUsedInIface = 1 << iota
|
||||||
SymFlagItab
|
SymFlagItab
|
||||||
SymFlagDict
|
SymFlagDict
|
||||||
|
SymFlagPkgInit
|
||||||
)
|
)
|
||||||
|
|
||||||
// Returns the length of the name of the symbol.
|
// Returns the length of the name of the symbol.
|
||||||
|
|
@ -333,6 +334,7 @@ func (s *Sym) IsGoType() bool { return s.Flag()&SymFlagGoType != 0 }
|
||||||
func (s *Sym) UsedInIface() bool { return s.Flag2()&SymFlagUsedInIface != 0 }
|
func (s *Sym) UsedInIface() bool { return s.Flag2()&SymFlagUsedInIface != 0 }
|
||||||
func (s *Sym) IsItab() bool { return s.Flag2()&SymFlagItab != 0 }
|
func (s *Sym) IsItab() bool { return s.Flag2()&SymFlagItab != 0 }
|
||||||
func (s *Sym) IsDict() bool { return s.Flag2()&SymFlagDict != 0 }
|
func (s *Sym) IsDict() bool { return s.Flag2()&SymFlagDict != 0 }
|
||||||
|
func (s *Sym) IsPkgInit() bool { return s.Flag2()&SymFlagPkgInit != 0 }
|
||||||
|
|
||||||
func (s *Sym) SetName(x string, w *Writer) {
|
func (s *Sym) SetName(x string, w *Writer) {
|
||||||
binary.LittleEndian.PutUint32(s[:], uint32(len(x)))
|
binary.LittleEndian.PutUint32(s[:], uint32(len(x)))
|
||||||
|
|
|
||||||
|
|
@ -724,6 +724,9 @@ const (
|
||||||
// IsPcdata indicates this is a pcdata symbol.
|
// IsPcdata indicates this is a pcdata symbol.
|
||||||
AttrPcdata
|
AttrPcdata
|
||||||
|
|
||||||
|
// PkgInit indicates this is a compiler-generated package init func.
|
||||||
|
AttrPkgInit
|
||||||
|
|
||||||
// attrABIBase is the value at which the ABI is encoded in
|
// attrABIBase is the value at which the ABI is encoded in
|
||||||
// Attribute. This must be last; all bits after this are
|
// Attribute. This must be last; all bits after this are
|
||||||
// assumed to be an ABI value.
|
// assumed to be an ABI value.
|
||||||
|
|
@ -752,6 +755,7 @@ func (a *Attribute) UsedInIface() bool { return a.load()&AttrUsedInIface
|
||||||
func (a *Attribute) ContentAddressable() bool { return a.load()&AttrContentAddressable != 0 }
|
func (a *Attribute) ContentAddressable() bool { return a.load()&AttrContentAddressable != 0 }
|
||||||
func (a *Attribute) ABIWrapper() bool { return a.load()&AttrABIWrapper != 0 }
|
func (a *Attribute) ABIWrapper() bool { return a.load()&AttrABIWrapper != 0 }
|
||||||
func (a *Attribute) IsPcdata() bool { return a.load()&AttrPcdata != 0 }
|
func (a *Attribute) IsPcdata() bool { return a.load()&AttrPcdata != 0 }
|
||||||
|
func (a *Attribute) IsPkgInit() bool { return a.load()&AttrPkgInit != 0 }
|
||||||
|
|
||||||
func (a *Attribute) Set(flag Attribute, value bool) {
|
func (a *Attribute) Set(flag Attribute, value bool) {
|
||||||
for {
|
for {
|
||||||
|
|
@ -800,6 +804,7 @@ var textAttrStrings = [...]struct {
|
||||||
{bit: AttrIndexed, s: ""},
|
{bit: AttrIndexed, s: ""},
|
||||||
{bit: AttrContentAddressable, s: ""},
|
{bit: AttrContentAddressable, s: ""},
|
||||||
{bit: AttrABIWrapper, s: "ABIWRAPPER"},
|
{bit: AttrABIWrapper, s: "ABIWRAPPER"},
|
||||||
|
{bit: AttrPkgInit, s: "PKGINIT"},
|
||||||
}
|
}
|
||||||
|
|
||||||
// String formats a for printing in as part of a TEXT prog.
|
// String formats a for printing in as part of a TEXT prog.
|
||||||
|
|
|
||||||
|
|
@ -344,6 +344,9 @@ func (w *writer) Sym(s *LSym) {
|
||||||
if strings.HasPrefix(s.Name, w.ctxt.Pkgpath) && strings.HasPrefix(s.Name[len(w.ctxt.Pkgpath):], ".") && strings.HasPrefix(s.Name[len(w.ctxt.Pkgpath)+1:], objabi.GlobalDictPrefix) {
|
if strings.HasPrefix(s.Name, w.ctxt.Pkgpath) && strings.HasPrefix(s.Name[len(w.ctxt.Pkgpath):], ".") && strings.HasPrefix(s.Name[len(w.ctxt.Pkgpath)+1:], objabi.GlobalDictPrefix) {
|
||||||
flag2 |= goobj.SymFlagDict
|
flag2 |= goobj.SymFlagDict
|
||||||
}
|
}
|
||||||
|
if s.IsPkgInit() {
|
||||||
|
flag2 |= goobj.SymFlagPkgInit
|
||||||
|
}
|
||||||
name := s.Name
|
name := s.Name
|
||||||
if strings.HasPrefix(name, "gofile..") {
|
if strings.HasPrefix(name, "gofile..") {
|
||||||
name = filepath.ToSlash(name)
|
name = filepath.ToSlash(name)
|
||||||
|
|
|
||||||
|
|
@ -193,6 +193,7 @@ func (ctxt *Link) InitTextSym(s *LSym, flag int, start src.XPos) {
|
||||||
s.Set(AttrABIWrapper, flag&ABIWRAPPER != 0)
|
s.Set(AttrABIWrapper, flag&ABIWRAPPER != 0)
|
||||||
s.Set(AttrNeedCtxt, flag&NEEDCTXT != 0)
|
s.Set(AttrNeedCtxt, flag&NEEDCTXT != 0)
|
||||||
s.Set(AttrNoFrame, flag&NOFRAME != 0)
|
s.Set(AttrNoFrame, flag&NOFRAME != 0)
|
||||||
|
s.Set(AttrPkgInit, flag&PKGINIT != 0)
|
||||||
s.Type = objabi.STEXT
|
s.Type = objabi.STEXT
|
||||||
ctxt.Text = append(ctxt.Text, s)
|
ctxt.Text = append(ctxt.Text, s)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -55,4 +55,7 @@ const (
|
||||||
|
|
||||||
// Function is an ABI wrapper.
|
// Function is an ABI wrapper.
|
||||||
ABIWRAPPER = 4096
|
ABIWRAPPER = 4096
|
||||||
|
|
||||||
|
// Function is a compiler-generated package init function.
|
||||||
|
PKGINIT = 8192
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -1190,6 +1190,15 @@ func (l *Loader) IsDict(i Sym) bool {
|
||||||
return r.Sym(li).IsDict()
|
return r.Sym(li).IsDict()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns whether this symbol is a compiler-generated package init func.
|
||||||
|
func (l *Loader) IsPkgInit(i Sym) bool {
|
||||||
|
if l.IsExternal(i) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
r, li := l.toLocal(i)
|
||||||
|
return r.Sym(li).IsPkgInit()
|
||||||
|
}
|
||||||
|
|
||||||
// Return whether this is a trampoline of a deferreturn call.
|
// Return whether this is a trampoline of a deferreturn call.
|
||||||
func (l *Loader) IsDeferReturnTramp(i Sym) bool {
|
func (l *Loader) IsDeferReturnTramp(i Sym) bool {
|
||||||
return l.deferReturnTramp[i]
|
return l.deferReturnTramp[i]
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue