update support for Go 1.17 in time for beta1

Back in early April we added initial support for Go 1.17,
working on a commit from master at that time. For that to work, we just
needed to add a couple of packages to runtimeRelated and tweak printFile
a bit to not break the new "//go:build" directives.

A significant amount of changes have landed since, though, and the tests
broke in multiple ways.

Most notably, the new register ABI is enabled by default for GOOS=amd64.
That affected garble indirectly in two ways: there's a new internal
package to add to runtimeRelated, and we must make reverse.txt more
clever in making its output constant across ABIs.

Another noticeable change is that Go 1.17 changes how its own version is
injected into the runtime package. It used to be via a constant in
runtime/internal/sys, such as:

	const TheVersion = `devel ...`

Since we couldn't override such constants via the linker's -X flag,
we had to directly alter the declaration while compiling.

Thankfully, Go 1.17 simply uses a "var buildVersion string" in the
runtime package, and its value is injected by the linker.
This means we can now override it with the linker's -X flag.

We make the code to alter TheVersion for Go 1.16 a bit more clever,
to not break the package when building with Go 1.17.

Finally, our hack to work around ambiguous TOOLEXEC_IMPORTPATH values
now only kicks in for non-test packages, since Go 1.17 includes our
upstream fix. Otherwise, some tests would end up with the ".test"
variant suffix added a second time:

	test/bar [test/bar.test] [test/bar [test/bar.test].test]

All the code to keep compatibility with Go 1.16.x remains in place.
We're still leaving TODOs to remind ourselves to remove it or simplify
it once we remove support for 1.16.x.

The 1.17 development freeze has already been in place for a month,
and beta1 is due to come this week, so it's unlikely that Go will change
in any considerable way at this point. Hence, we can say that support
for 1.17 is done.

Fixes #347.
pull/358/head
Daniel Martí 3 years ago committed by lu4p
parent ff361f6b15
commit 5e3cdf89a8

@ -31,7 +31,7 @@ jobs:
steps:
- name: Install Go
env:
GO_COMMIT: f60aa7a18cedd8f09dabbef9840893442fd2bda4 # 2021-04-07
GO_COMMIT: 1419ca7cead4438c8c9f17d8901aeecd9c72f577 # 2021-05-27
run: |
cd $HOME
mkdir $HOME/gotip

@ -358,7 +358,7 @@ func mainErr(args []string) error {
// Workaround for https://github.com/golang/go/issues/44963.
// TODO(mvdan): remove once we only support Go 1.17 and later.
if tool == "compile" {
if tool == "compile" && !strings.Contains(toolexecImportPath, ".test]") {
isTestPkg := false
_, paths := splitFlagsFromFiles(args, ".go")
for _, path := range paths {
@ -695,10 +695,15 @@ func transformCompile(args []string) ([]string, error) {
// const TheVersion = `devel ...`
//
// Don't touch the source in any other way.
// TODO: remove once we only support Go 1.17 and later,
// as from that point we can just rely on linking -X flags.
if name != "zversion.go" {
break
}
spec := file.Decls[0].(*ast.GenDecl).Specs[0].(*ast.ValueSpec)
if len(spec.Names) != 1 || spec.Names[0].Name != "TheVersion" {
break
}
lit := spec.Values[0].(*ast.BasicLit)
lit.Value = "`unknown`"
case strings.HasPrefix(name, "_cgo_"):
@ -882,9 +887,10 @@ var runtimeRelated = map[string]bool{
"vendor/golang.org/x/net/dns/dnsmessage": true,
"vendor/golang.org/x/net/route": true,
// Manual additions for Go 1.17 as of April 2021.
"internal/abi": true,
"internal/itoa": true,
// Manual additions for Go 1.17 as of June 2021.
"internal/abi": true,
"internal/itoa": true,
"internal/goexperiment": true,
}
// isPrivate checks if a package import path should be considered private,
@ -1540,6 +1546,10 @@ func transformLink(args []string) ([]string, error) {
flags = append(flags, fmt.Sprintf("-X=%s.%s=%s", newPkg, newName, str))
})
// Starting in Go 1.17, Go's version is implicitly injected by the linker.
// It's the same method as -X, so we can override it with an extra flag.
flags = append(flags, "-X=runtime.buildVersion=unknown")
// Ensure we strip the -buildid flag, to not leak any build IDs for the
// link operation or the main package's compilation.
flags = flagSetValue(flags, "-buildid", "")

@ -101,13 +101,16 @@ func (*ExportedLibType) ExportedLibMethod(w io.Writer) error {
func printStackTrace(w io.Writer) error {
// Panic outputs include "0xNN" pointers and offsets which change
// between platforms.
// The format also changes depending on the ABI.
// Strip them out here, to have portable static stdout files.
rxVariableSuffix := regexp.MustCompile(`0x[0-9a-f]+`)
rxCallArgs := regexp.MustCompile(`\(({|0x)[^)]+\)|\(\)`)
rxPointer := regexp.MustCompile(`0x[0-9a-f]+`)
// Keep this comment here, because comments affect line numbers.
stack := debug.Stack()
stack = rxVariableSuffix.ReplaceAll(stack, []byte("0x??"))
stack = rxCallArgs.ReplaceAll(stack, []byte("(...)"))
stack = rxPointer.ReplaceAll(stack, []byte("0x??"))
_, err := w.Write(stack)
return err
}
@ -134,17 +137,17 @@ var _ = struct{SomeField int}(UnobfuscatedStruct{})
lib filename: test/main/lib/lib.go
goroutine 1 [running]:
runtime/debug.Stack(0x??, 0x??, 0x??)
runtime/debug.Stack(...)
runtime/debug/stack.go:24 +0x??
test/main/lib.printStackTrace(0x??, 0x??, 0x??, 0x??)
test/main/lib/lib.go:28 +0x??
test/main/lib.(*ExportedLibType).ExportedLibMethod(0x??, 0x??, 0x??, 0x??, 0x??)
test/main/lib.printStackTrace(...)
test/main/lib/lib.go:30 +0x??
test/main/lib.(*ExportedLibType).ExportedLibMethod(...)
test/main/lib/lib.go:17 +0x??
main.unexportedMainFunc.func1(...)
test/main/main.go:21
main.unexportedMainFunc()
main.unexportedMainFunc(...)
test/main/main.go:25 +0x??
main.main()
main.main(...)
test/main/main.go:11 +0x??
main filename: test/main/main.go

Loading…
Cancel
Save