]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/internal/obj: flag init functions in object file
authorThan McIntosh <thanm@google.com>
Thu, 26 Jan 2023 20:12:00 +0000 (15:12 -0500)
committerThan McIntosh <thanm@google.com>
Mon, 6 Feb 2023 20:25:30 +0000 (20:25 +0000)
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>

src/cmd/compile/internal/ir/abi.go
src/cmd/compile/internal/ir/func.go
src/cmd/compile/internal/pkginit/init.go
src/cmd/internal/goobj/objfile.go
src/cmd/internal/obj/link.go
src/cmd/internal/obj/objfile.go
src/cmd/internal/obj/plist.go
src/cmd/internal/obj/textflag.go
src/cmd/link/internal/loader/loader.go

index 8cd1606e660eabe311f58e0ee9e9fdb9c21fe47e..041448fb29639028f5fa492a53d17dfbb452a4a4 100644 (file)
@@ -53,6 +53,9 @@ func setupTextLSym(f *Func, flag int) {
        if f.ReflectMethod() {
                flag |= obj.REFLECTMETHOD
        }
+       if f.IsPackageInit() {
+               flag |= obj.PKGINIT
+       }
 
        // Clumsy but important.
        // For functions that could be on the path of invoking a deferred
index 8f56c6f2f6862c802001223917f8d745d70bfce0..fba62283d5bad34d637e96ca728cbe984509e5fb 100644 (file)
@@ -204,6 +204,7 @@ const (
        funcInstrumentBody           // add race/msan/asan instrumentation during SSA construction
        funcOpenCodedDeferDisallowed // can't do open-coded defers
        funcClosureCalled            // closure is only immediately called; used by escape analysis
+       funcPackageInit              // compiler emitted .init func for package
 )
 
 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) OpenCodedDeferDisallowed() bool { return f.flags&funcOpenCodedDeferDisallowed != 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) 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) SetOpenCodedDeferDisallowed(b bool) { f.flags.set(funcOpenCodedDeferDisallowed, 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) {
        if base.Debug.WB != 0 {
index 9d4c4357643d5d43033d155d1b3bff93423408f5..fac1ad790f352af265b1f6d411153d0706376299 100644 (file)
@@ -36,6 +36,7 @@ func MakeInit() {
        }
        fn.Dcl = append(fn.Dcl, typecheck.InitTodoFunc.Dcl...)
        typecheck.InitTodoFunc.Dcl = nil
+       fn.SetIsPackageInit(true)
 
        // Suppress useless "can inline" diagnostics.
        // Init functions are only called dynamically.
index 7b985fae53b89a89c7d89ffb1abe369447dd5b6a..547b8264950f45f50a61e1ed424044648bde8026 100644 (file)
@@ -303,6 +303,7 @@ const (
        SymFlagUsedInIface = 1 << iota
        SymFlagItab
        SymFlagDict
+       SymFlagPkgInit
 )
 
 // 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) IsItab() bool        { return s.Flag2()&SymFlagItab != 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) {
        binary.LittleEndian.PutUint32(s[:], uint32(len(x)))
index 6d40b334afda37ac6e018e9b0526c8bfb194a604..d153afbfae0f0afdf14660975603688a06fbaeb8 100644 (file)
@@ -724,6 +724,9 @@ const (
        // IsPcdata indicates this is a pcdata symbol.
        AttrPcdata
 
+       // PkgInit indicates this is a compiler-generated package init func.
+       AttrPkgInit
+
        // attrABIBase is the value at which the ABI is encoded in
        // Attribute. This must be last; all bits after this are
        // 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) ABIWrapper() bool         { return a.load()&AttrABIWrapper != 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) {
        for {
@@ -800,6 +804,7 @@ var textAttrStrings = [...]struct {
        {bit: AttrIndexed, s: ""},
        {bit: AttrContentAddressable, s: ""},
        {bit: AttrABIWrapper, s: "ABIWRAPPER"},
+       {bit: AttrPkgInit, s: "PKGINIT"},
 }
 
 // String formats a for printing in as part of a TEXT prog.
index 85e49e248c13bc375c19c0f53bc9324c04bf868e..73c29d9686590b57237c9e1beb8fae074c89d47b 100644 (file)
@@ -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) {
                flag2 |= goobj.SymFlagDict
        }
+       if s.IsPkgInit() {
+               flag2 |= goobj.SymFlagPkgInit
+       }
        name := s.Name
        if strings.HasPrefix(name, "gofile..") {
                name = filepath.ToSlash(name)
index fe9d2e1fb7401f4e16e2072f49318b21acb36166..835f37f2ffc2eb1ec8aa26e8cf73b2ebb3d727cc 100644 (file)
@@ -193,6 +193,7 @@ func (ctxt *Link) InitTextSym(s *LSym, flag int, start src.XPos) {
        s.Set(AttrABIWrapper, flag&ABIWRAPPER != 0)
        s.Set(AttrNeedCtxt, flag&NEEDCTXT != 0)
        s.Set(AttrNoFrame, flag&NOFRAME != 0)
+       s.Set(AttrPkgInit, flag&PKGINIT != 0)
        s.Type = objabi.STEXT
        ctxt.Text = append(ctxt.Text, s)
 
index 5ae75027c2f2b544f7b7eb91d3f03fe7d33a7353..bf9c8c99f16cdc9dae117b78190b1f0fb55c1742 100644 (file)
@@ -55,4 +55,7 @@ const (
 
        // Function is an ABI wrapper.
        ABIWRAPPER = 4096
+
+       // Function is a compiler-generated package init function.
+       PKGINIT = 8192
 )
index 2ac17f4f163a0100ceb35d55e4090b5b451ed851..e3ee819a9db1b4fa5d9f6b10449838006d597cf3 100644 (file)
@@ -1190,6 +1190,15 @@ func (l *Loader) IsDict(i Sym) bool {
        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.
 func (l *Loader) IsDeferReturnTramp(i Sym) bool {
        return l.deferReturnTramp[i]