diff options
author | Keith Randall <khr@golang.org> | 2023-01-12 20:25:39 -0800 |
---|---|---|
committer | Keith Randall <khr@golang.org> | 2023-03-03 23:11:37 +0000 |
commit | ce2a609909d9de3391a99a00fe140506f724f933 (patch) | |
tree | 73fcbd68f8148f993ca3717ea5fd3bec224c7f56 /src/cmd/compile | |
parent | cd6d225bd30608544ecf4a3e5a7aa1d0607a66db (diff) | |
download | go-git-ce2a609909d9de3391a99a00fe140506f724f933.tar.gz |
cmd/link: establish dependable package initialization order
As described here:
https://github.com/golang/go/issues/31636#issuecomment-493271830
"Find the lexically earliest package that is not initialized yet,
but has had all its dependencies initialized, initialize that package,
and repeat."
Simplify the runtime a bit, by just computing the ordering required
in the linker and giving a list to the runtime.
Update #31636
Fixes #57411
RELNOTE=yes
Change-Id: I1e4d3878ebe6e8953527aedb730824971d722cac
Reviewed-on: https://go-review.googlesource.com/c/go/+/462035
Reviewed-by: Than McIntosh <thanm@google.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
Diffstat (limited to 'src/cmd/compile')
-rw-r--r-- | src/cmd/compile/internal/pkginit/init.go | 18 |
1 files changed, 12 insertions, 6 deletions
diff --git a/src/cmd/compile/internal/pkginit/init.go b/src/cmd/compile/internal/pkginit/init.go index 84f4c2cfe3..f8d5ee08a5 100644 --- a/src/cmd/compile/internal/pkginit/init.go +++ b/src/cmd/compile/internal/pkginit/init.go @@ -13,6 +13,7 @@ import ( "cmd/compile/internal/typecheck" "cmd/compile/internal/types" "cmd/internal/obj" + "cmd/internal/objabi" "cmd/internal/src" "fmt" "os" @@ -201,15 +202,20 @@ func Task() *ir.Name { sym.Def = task lsym := task.Linksym() ot := 0 - ot = objw.Uintptr(lsym, ot, 0) // state: not initialized yet - ot = objw.Uintptr(lsym, ot, uint64(len(deps))) - ot = objw.Uintptr(lsym, ot, uint64(len(fns))) - for _, d := range deps { - ot = objw.SymPtr(lsym, ot, d, 0) - } + ot = objw.Uint32(lsym, ot, 0) // state: not initialized yet + ot = objw.Uint32(lsym, ot, uint32(len(fns))) for _, f := range fns { ot = objw.SymPtr(lsym, ot, f, 0) } + + // Add relocations which tell the linker all of the packages + // that this package depends on (and thus, all of the packages + // that need to be initialized before this one). + for _, d := range deps { + r := obj.Addrel(lsym) + r.Type = objabi.R_INITORDER + r.Sym = d + } // An initTask has pointers, but none into the Go heap. // It's not quite read only, the state field must be modifiable. objw.Global(lsym, int32(ot), obj.NOPTR) |