Skip to content

Commit

Permalink
cmd/internal/obj: flag init functions in object file
Browse files Browse the repository at this point in the history
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 golang#2559.
Updates golang#36021.
Updates golang#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>
  • Loading branch information
thanm authored and johanbrandhorst committed Feb 12, 2023
1 parent a5029fd commit 1509858
Show file tree
Hide file tree
Showing 9 changed files with 30 additions and 0 deletions.
3 changes: 3 additions & 0 deletions src/cmd/compile/internal/ir/abi.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 3 additions & 0 deletions src/cmd/compile/internal/ir/func.go
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,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 {
Expand All @@ -229,6 +230,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) }
Expand All @@ -244,6 +246,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 {
Expand Down
1 change: 1 addition & 0 deletions src/cmd/compile/internal/pkginit/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
2 changes: 2 additions & 0 deletions src/cmd/internal/goobj/objfile.go
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,7 @@ const (
SymFlagUsedInIface = 1 << iota
SymFlagItab
SymFlagDict
SymFlagPkgInit
)

// Returns the length of the name of the symbol.
Expand Down Expand Up @@ -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)))
Expand Down
5 changes: 5 additions & 0 deletions src/cmd/internal/obj/link.go
Original file line number Diff line number Diff line change
Expand Up @@ -796,6 +796,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.
Expand Down Expand Up @@ -824,6 +827,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 {
Expand Down Expand Up @@ -872,6 +876,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.
Expand Down
3 changes: 3 additions & 0 deletions src/cmd/internal/obj/objfile.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
1 change: 1 addition & 0 deletions src/cmd/internal/obj/plist.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down
3 changes: 3 additions & 0 deletions src/cmd/internal/obj/textflag.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,4 +55,7 @@ const (

// Function is an ABI wrapper.
ABIWRAPPER = 4096

// Function is a compiler-generated package init function.
PKGINIT = 8192
)
9 changes: 9 additions & 0 deletions src/cmd/link/internal/loader/loader.go
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down

0 comments on commit 1509858

Please sign in to comment.