Skip to content

Commit 20e7084

Browse files
thanmeric
authored andcommitted
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 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 <[email protected]> Run-TryBot: Than McIntosh <[email protected]> TryBot-Result: Gopher Robot <[email protected]>
1 parent 12141b7 commit 20e7084

File tree

9 files changed

+30
-0
lines changed

9 files changed

+30
-0
lines changed

src/cmd/compile/internal/ir/abi.go

+3
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,9 @@ func setupTextLSym(f *Func, flag int) {
5353
if f.ReflectMethod() {
5454
flag |= obj.REFLECTMETHOD
5555
}
56+
if f.IsPackageInit() {
57+
flag |= obj.PKGINIT
58+
}
5659

5760
// Clumsy but important.
5861
// For functions that could be on the path of invoking a deferred

src/cmd/compile/internal/ir/func.go

+3
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,7 @@ const (
204204
funcInstrumentBody // add race/msan/asan instrumentation during SSA construction
205205
funcOpenCodedDeferDisallowed // can't do open-coded defers
206206
funcClosureCalled // closure is only immediately called; used by escape analysis
207+
funcPackageInit // compiler emitted .init func for package
207208
)
208209

209210
type SymAndPos struct {
@@ -225,6 +226,7 @@ func (f *Func) ExportInline() bool { return f.flags&funcExportInline
225226
func (f *Func) InstrumentBody() bool { return f.flags&funcInstrumentBody != 0 }
226227
func (f *Func) OpenCodedDeferDisallowed() bool { return f.flags&funcOpenCodedDeferDisallowed != 0 }
227228
func (f *Func) ClosureCalled() bool { return f.flags&funcClosureCalled != 0 }
229+
func (f *Func) IsPackageInit() bool { return f.flags&funcPackageInit != 0 }
228230

229231
func (f *Func) SetDupok(b bool) { f.flags.set(funcDupok, b) }
230232
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
240242
func (f *Func) SetInstrumentBody(b bool) { f.flags.set(funcInstrumentBody, b) }
241243
func (f *Func) SetOpenCodedDeferDisallowed(b bool) { f.flags.set(funcOpenCodedDeferDisallowed, b) }
242244
func (f *Func) SetClosureCalled(b bool) { f.flags.set(funcClosureCalled, b) }
245+
func (f *Func) SetIsPackageInit(b bool) { f.flags.set(funcPackageInit, b) }
243246

244247
func (f *Func) SetWBPos(pos src.XPos) {
245248
if base.Debug.WB != 0 {

src/cmd/compile/internal/pkginit/init.go

+1
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ func MakeInit() {
3636
}
3737
fn.Dcl = append(fn.Dcl, typecheck.InitTodoFunc.Dcl...)
3838
typecheck.InitTodoFunc.Dcl = nil
39+
fn.SetIsPackageInit(true)
3940

4041
// Suppress useless "can inline" diagnostics.
4142
// Init functions are only called dynamically.

src/cmd/internal/goobj/objfile.go

+2
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,7 @@ const (
303303
SymFlagUsedInIface = 1 << iota
304304
SymFlagItab
305305
SymFlagDict
306+
SymFlagPkgInit
306307
)
307308

308309
// Returns the length of the name of the symbol.
@@ -333,6 +334,7 @@ func (s *Sym) IsGoType() bool { return s.Flag()&SymFlagGoType != 0 }
333334
func (s *Sym) UsedInIface() bool { return s.Flag2()&SymFlagUsedInIface != 0 }
334335
func (s *Sym) IsItab() bool { return s.Flag2()&SymFlagItab != 0 }
335336
func (s *Sym) IsDict() bool { return s.Flag2()&SymFlagDict != 0 }
337+
func (s *Sym) IsPkgInit() bool { return s.Flag2()&SymFlagPkgInit != 0 }
336338

337339
func (s *Sym) SetName(x string, w *Writer) {
338340
binary.LittleEndian.PutUint32(s[:], uint32(len(x)))

src/cmd/internal/obj/link.go

+5
Original file line numberDiff line numberDiff line change
@@ -724,6 +724,9 @@ const (
724724
// IsPcdata indicates this is a pcdata symbol.
725725
AttrPcdata
726726

727+
// PkgInit indicates this is a compiler-generated package init func.
728+
AttrPkgInit
729+
727730
// attrABIBase is the value at which the ABI is encoded in
728731
// Attribute. This must be last; all bits after this are
729732
// assumed to be an ABI value.
@@ -752,6 +755,7 @@ func (a *Attribute) UsedInIface() bool { return a.load()&AttrUsedInIface
752755
func (a *Attribute) ContentAddressable() bool { return a.load()&AttrContentAddressable != 0 }
753756
func (a *Attribute) ABIWrapper() bool { return a.load()&AttrABIWrapper != 0 }
754757
func (a *Attribute) IsPcdata() bool { return a.load()&AttrPcdata != 0 }
758+
func (a *Attribute) IsPkgInit() bool { return a.load()&AttrPkgInit != 0 }
755759

756760
func (a *Attribute) Set(flag Attribute, value bool) {
757761
for {
@@ -800,6 +804,7 @@ var textAttrStrings = [...]struct {
800804
{bit: AttrIndexed, s: ""},
801805
{bit: AttrContentAddressable, s: ""},
802806
{bit: AttrABIWrapper, s: "ABIWRAPPER"},
807+
{bit: AttrPkgInit, s: "PKGINIT"},
803808
}
804809

805810
// String formats a for printing in as part of a TEXT prog.

src/cmd/internal/obj/objfile.go

+3
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,9 @@ func (w *writer) Sym(s *LSym) {
344344
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) {
345345
flag2 |= goobj.SymFlagDict
346346
}
347+
if s.IsPkgInit() {
348+
flag2 |= goobj.SymFlagPkgInit
349+
}
347350
name := s.Name
348351
if strings.HasPrefix(name, "gofile..") {
349352
name = filepath.ToSlash(name)

src/cmd/internal/obj/plist.go

+1
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,7 @@ func (ctxt *Link) InitTextSym(s *LSym, flag int, start src.XPos) {
193193
s.Set(AttrABIWrapper, flag&ABIWRAPPER != 0)
194194
s.Set(AttrNeedCtxt, flag&NEEDCTXT != 0)
195195
s.Set(AttrNoFrame, flag&NOFRAME != 0)
196+
s.Set(AttrPkgInit, flag&PKGINIT != 0)
196197
s.Type = objabi.STEXT
197198
ctxt.Text = append(ctxt.Text, s)
198199

src/cmd/internal/obj/textflag.go

+3
Original file line numberDiff line numberDiff line change
@@ -55,4 +55,7 @@ const (
5555

5656
// Function is an ABI wrapper.
5757
ABIWRAPPER = 4096
58+
59+
// Function is a compiler-generated package init function.
60+
PKGINIT = 8192
5861
)

src/cmd/link/internal/loader/loader.go

+9
Original file line numberDiff line numberDiff line change
@@ -1182,6 +1182,15 @@ func (l *Loader) IsDict(i Sym) bool {
11821182
return r.Sym(li).IsDict()
11831183
}
11841184

1185+
// Returns whether this symbol is a compiler-generated package init func.
1186+
func (l *Loader) IsPkgInit(i Sym) bool {
1187+
if l.IsExternal(i) {
1188+
return false
1189+
}
1190+
r, li := l.toLocal(i)
1191+
return r.Sym(li).IsPkgInit()
1192+
}
1193+
11851194
// Return whether this is a trampoline of a deferreturn call.
11861195
func (l *Loader) IsDeferReturnTramp(i Sym) bool {
11871196
return l.deferReturnTramp[i]

0 commit comments

Comments
 (0)