summaryrefslogtreecommitdiff
path: root/src/cmd/compile
diff options
context:
space:
mode:
authorKeith Randall <khr@golang.org>2023-01-12 20:25:39 -0800
committerKeith Randall <khr@golang.org>2023-03-03 23:11:37 +0000
commitce2a609909d9de3391a99a00fe140506f724f933 (patch)
tree73fcbd68f8148f993ca3717ea5fd3bec224c7f56 /src/cmd/compile
parentcd6d225bd30608544ecf4a3e5a7aa1d0607a66db (diff)
downloadgo-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.go18
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)