Repository navigation
runtime: fully implement GOROOT and GODEBUG - #5885
jakebailey wants to merge 4 commits into
Conversation
|
Hm, I have some work to do, then |
4499a2b to
2fbbebf
Compare
2fbbebf to
35b4365
Compare
|
@jakebailey thank you for working on this. So I'm on the same page, is the new optimisation pass aimed at removing the FIPS code that is reachable through runtime.GODEBUG? |
|
No, your whole-module replacement gets rid of a lot more since all I'm working on is what's upstream. Haven't really had the time to look into something that combines the two, if such a thing is even possible. |
Thank you for adding The issue is this only removes the GODEBUG support when no reader survives, and the FIPS code provides such a reader because Settings.Value isn't a compile time constant on bare metal. What if we were try something like this
|
|
The transform pass is actually required to make the PR work, unfortunately... |
|
Seems like with some improvements to interp, the existing godebug package can actually be trimmed away without being replaced, maybe. Screwing around with it |
opps, my mistake. The transform pass works around interps inability to see through Settings.Value because the defer and the atomic. Even if I propose a read only Settings.Value for bare metal, this won't solve for non bare metal builds. Mia culpa, please ignore my first suggestion. |
|
Can you see if https://github.com/jakebailey/tinygo/tree/interp-init-evaluation does the trick? or rather, this PR + that branch maybe 😄 |
35b4365 to
9393554
Compare
|
@jakebailey can you please rebase and resolve merge confict? Thanks! |
9393554 to
153c83b
Compare
|
Sorry @jakebailey just one more merge conflict, please. 😸 |
153c83b to
47a1253
Compare
|
|
||
| if gorootEnvEnabled() { | ||
| if value := startupEnv("GOROOT"); value != "" { | ||
| goroot = value |
There was a problem hiding this comment.
This puts the feature-gate calls in the same initializer that parses osArgs and osEnv. Interp runs before the optimizer resolves these gates, so it cannot interpret this initializer and leaves the parsing code to run at startup. Could we split the gate checks into a second initializer?
env = append(env, s[start:])
}
+}
+
+func init() {
if gorootEnvEnabled() {There was a problem hiding this comment.
Pushed that, but not really clear it did much?
47a1253 to
898fee5
Compare
|
Thanks @jakebailey. The rebase keeps the interp work intact. I found one remaining regression: with package main
import _ "crypto/sha256"
func main() {}
|
898fee5 to
bc532bb
Compare
|
I revalidated the latest PR head, With Go 1.27.3, the crypto repro from my earlier comment matches package main
import _ "crypto/sha256"
func main() {}Built for Pico with There is a separate regression with Go 1.25.14. This program grows from 8,824 bytes on package main
import "time"
func main() {
time.Sleep(time.Second)
}Go 1.25's This also explains the two CI failures, because both jobs use Go 1.25. If Go 1.25 is no longer supported for 0.45, I think we can accept this regression after the minimum Go version and the CI toolchains move to 1.26, as tracked in #5984. |
bc532bb to
6545b50
Compare
|
Was already looking; try again. Not happy about the extra passes though. |
If you can wait for #6084 to land then this might fix itself. |
Go 1.25 is no longer supported upstream. Running these jobs with Go 1.26 lets tinygo-org#5885 land without failures caused only by Go 1.25 GODEBUG settings.
Go defines runtime.GOROOT from the process environment captured at startup, with the build-time root as a fallback. TinyGo only used the build-time value, so binaries could not select a relocated toolchain root. Capture GOROOT before user package initialization and retain that value after later environment changes.
internal/godebug needs both the compiled defaults and the current environment value when it registers with the runtime. Without that initial state, package behavior can differ from the selected Go version and startup environment until the process changes GODEBUG. Pass the main package defaults from go list to the runtime and retain GODEBUG changes that happen before internal/godebug registers.
Removing GODEBUG must immediately expose the compiled defaults again. TinyGo did not notify internal/godebug for every unset path, which let an old environment override remain cached after cleanup or Clearenv.
GOROOT and GODEBUG startup support retains environment access even when programs do not use either feature. Go 1.25 also registers the GODEBUG updater without any setting reads, retaining its parser and atomic operations. This adds imports and code to small WASI and bare-metal programs and prevents AVR builds with LLVM 15. Unused startup support should not impose those costs on programs that never read the settings. Startup settings must also remain available to compile-time initialization so disabled FIPS self-tests do not survive in multicore builds.
6545b50 to
2b2958a
Compare
This captures GOROOT and GODEBUG from the env at startup, then keeps things up to date when they're updated at runtime.
Eventually enables some stdlib testing, though they can't yet be enabled by this PR alone.