diff options
| author | Cherry Zhang <cherryyz@google.com> | 2020-05-21 14:08:32 -0400 |
|---|---|---|
| committer | Cherry Zhang <cherryyz@google.com> | 2020-05-21 14:08:32 -0400 |
| commit | 6097f7cf7a9a9bf877f6f49112ffcc2d0f0e7e75 (patch) | |
| tree | c42265e0cfb4ac2bbcf4a9ed9432748997d2362a /src/cmd | |
| parent | 8e4ab9cb4c28649be36f82a02d04eb1cb31d02c9 (diff) | |
| parent | c847589ad06a1acfcceaac7b230c0d5a826caab8 (diff) | |
| download | go-6097f7cf7a9a9bf877f6f49112ffcc2d0f0e7e75.tar.xz | |
[dev.link] all: merge branch 'master' into dev.link
Change-Id: I85b653b621ad8cb2ef27886210ea2c4b7409b60d
Diffstat (limited to 'src/cmd')
| -rw-r--r-- | src/cmd/compile/internal/gc/pgen.go | 25 | ||||
| -rw-r--r-- | src/cmd/dist/build.go | 11 | ||||
| -rw-r--r-- | src/cmd/dist/buildruntime.go | 2 | ||||
| -rw-r--r-- | src/cmd/go.mod | 2 | ||||
| -rw-r--r-- | src/cmd/go.sum | 4 | ||||
| -rw-r--r-- | src/cmd/go/alldocs.go | 3 | ||||
| -rw-r--r-- | src/cmd/go/internal/cfg/cfg.go | 3 | ||||
| -rw-r--r-- | src/cmd/go/internal/help/helpdoc.go | 3 | ||||
| -rw-r--r-- | src/cmd/go/internal/modfetch/proxy.go | 10 | ||||
| -rw-r--r-- | src/cmd/go/internal/work/exec.go | 14 | ||||
| -rw-r--r-- | src/cmd/go/note_test.go | 2 | ||||
| -rw-r--r-- | src/cmd/go/testdata/script/issue36000.txt | 6 | ||||
| -rw-r--r-- | src/cmd/go/testdata/script/mod_gonoproxy.txt | 10 | ||||
| -rw-r--r-- | src/cmd/internal/obj/objfile.go | 8 | ||||
| -rw-r--r-- | src/cmd/internal/objabi/util.go | 11 | ||||
| -rw-r--r-- | src/cmd/link/internal/arm/asm.go | 6 | ||||
| -rw-r--r-- | src/cmd/link/internal/ld/fallocate_test.go | 50 | ||||
| -rw-r--r-- | src/cmd/link/internal/ld/outbuf_darwin.go | 17 | ||||
| -rw-r--r-- | src/cmd/link/internal/ld/pcln.go | 2 | ||||
| -rw-r--r-- | src/cmd/link/internal/loader/loader.go | 14 | ||||
| -rw-r--r-- | src/cmd/link/internal/ppc64/asm.go | 10 | ||||
| -rw-r--r-- | src/cmd/link/link_test.go | 19 | ||||
| -rw-r--r-- | src/cmd/vendor/modules.txt | 2 |
23 files changed, 179 insertions, 55 deletions
diff --git a/src/cmd/compile/internal/gc/pgen.go b/src/cmd/compile/internal/gc/pgen.go index 6ccd0b8d94..74654c86bc 100644 --- a/src/cmd/compile/internal/gc/pgen.go +++ b/src/cmd/compile/internal/gc/pgen.go @@ -271,7 +271,7 @@ func compile(fn *Node) { } } - if compilenow() { + if compilenow(fn) { compileSSA(fn, 0) } else { compilequeue = append(compilequeue, fn) @@ -282,10 +282,31 @@ func compile(fn *Node) { // If functions are not compiled immediately, // they are enqueued in compilequeue, // which is drained by compileFunctions. -func compilenow() bool { +func compilenow(fn *Node) bool { + // Issue 38068: if this function is a method AND an inline + // candidate AND was not inlined (yet), put it onto the compile + // queue instead of compiling it immediately. This is in case we + // wind up inlining it into a method wrapper that is generated by + // compiling a function later on in the xtop list. + if fn.IsMethod() && isInlinableButNotInlined(fn) { + return false + } return nBackendWorkers == 1 && Debug_compilelater == 0 } +// isInlinableButNotInlined returns true if 'fn' was marked as an +// inline candidate but then never inlined (presumably because we +// found no call sites). +func isInlinableButNotInlined(fn *Node) bool { + if fn.Func.Nname.Func.Inl == nil { + return false + } + if fn.Sym == nil { + return true + } + return !fn.Sym.Linksym().WasInlined() +} + const maxStackSize = 1 << 30 // compileSSA builds an SSA backend function, diff --git a/src/cmd/dist/build.go b/src/cmd/dist/build.go index d22ee1d361..9e2b4f33b8 100644 --- a/src/cmd/dist/build.go +++ b/src/cmd/dist/build.go @@ -31,7 +31,6 @@ var ( goos string goarm string go386 string - goamd64 string gomips string gomips64 string goppc64 string @@ -152,12 +151,6 @@ func xinit() { } go386 = b - b = os.Getenv("GOAMD64") - if b == "" { - b = "alignedjumps" - } - goamd64 = b - b = os.Getenv("GOMIPS") if b == "" { b = "hardfloat" @@ -230,7 +223,6 @@ func xinit() { // For tools being invoked but also for os.ExpandEnv. os.Setenv("GO386", go386) - os.Setenv("GOAMD64", goamd64) os.Setenv("GOARCH", goarch) os.Setenv("GOARM", goarm) os.Setenv("GOHOSTARCH", gohostarch) @@ -1171,9 +1163,6 @@ func cmdenv() { if goarch == "386" { xprintf(format, "GO386", go386) } - if goarch == "amd64" { - xprintf(format, "GOAMD64", goamd64) - } if goarch == "mips" || goarch == "mipsle" { xprintf(format, "GOMIPS", gomips) } diff --git a/src/cmd/dist/buildruntime.go b/src/cmd/dist/buildruntime.go index f11933c925..2744951597 100644 --- a/src/cmd/dist/buildruntime.go +++ b/src/cmd/dist/buildruntime.go @@ -42,7 +42,6 @@ func mkzversion(dir, file string) { // // const defaultGOROOT = <goroot> // const defaultGO386 = <go386> -// const defaultGOAMD64 = <goamd64> // const defaultGOARM = <goarm> // const defaultGOMIPS = <gomips> // const defaultGOMIPS64 = <gomips64> @@ -72,7 +71,6 @@ func mkzbootstrap(file string) { fmt.Fprintf(&buf, "import \"runtime\"\n") fmt.Fprintln(&buf) fmt.Fprintf(&buf, "const defaultGO386 = `%s`\n", go386) - fmt.Fprintf(&buf, "const defaultGOAMD64 = `%s`\n", goamd64) fmt.Fprintf(&buf, "const defaultGOARM = `%s`\n", goarm) fmt.Fprintf(&buf, "const defaultGOMIPS = `%s`\n", gomips) fmt.Fprintf(&buf, "const defaultGOMIPS64 = `%s`\n", gomips64) diff --git a/src/cmd/go.mod b/src/cmd/go.mod index 9c78cd14e6..d56dde8a2a 100644 --- a/src/cmd/go.mod +++ b/src/cmd/go.mod @@ -7,7 +7,7 @@ require ( github.com/ianlancetaylor/demangle v0.0.0-20200414190113-039b1ae3a340 // indirect golang.org/x/arch v0.0.0-20200511175325-f7c78586839d golang.org/x/crypto v0.0.0-20200429183012-4b2356b1ed79 - golang.org/x/mod v0.2.1-0.20200429172858-859b3ef565e2 + golang.org/x/mod v0.3.0 golang.org/x/sys v0.0.0-20200501145240-bc7a7d42d5c3 // indirect golang.org/x/tools v0.0.0-20200504152539-33427f1b0364 ) diff --git a/src/cmd/go.sum b/src/cmd/go.sum index f1b3754aad..922df777be 100644 --- a/src/cmd/go.sum +++ b/src/cmd/go.sum @@ -14,8 +14,8 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20200429183012-4b2356b1ed79 h1:IaQbIIB2X/Mp/DKctl6ROxz1KyMlKp4uyvL6+kQ7C88= golang.org/x/crypto v0.0.0-20200429183012-4b2356b1ed79/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.2.1-0.20200429172858-859b3ef565e2 h1:VUsRDZIYpMs3R7PyYeN7BSbDfYjhxaX6HlWvM5iAEqs= -golang.org/x/mod v0.2.1-0.20200429172858-859b3ef565e2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= diff --git a/src/cmd/go/alldocs.go b/src/cmd/go/alldocs.go index 5c1f7254bf..fdeef651c7 100644 --- a/src/cmd/go/alldocs.go +++ b/src/cmd/go/alldocs.go @@ -1754,9 +1754,6 @@ // GO386 // For GOARCH=386, the floating point instruction set. // Valid values are 387, sse2. -// GOAMD64 -// For GOARCH=amd64, jumps can be optionally be aligned such that they do not end on -// or cross 32 byte boundaries. Valid values are alignedjumps (default), normaljumps. // GOMIPS // For GOARCH=mips{,le}, whether to use floating point instructions. // Valid values are hardfloat (default), softfloat. diff --git a/src/cmd/go/internal/cfg/cfg.go b/src/cmd/go/internal/cfg/cfg.go index 21f55e852f..7f8f8e92be 100644 --- a/src/cmd/go/internal/cfg/cfg.go +++ b/src/cmd/go/internal/cfg/cfg.go @@ -241,7 +241,6 @@ var ( // Used in envcmd.MkEnv and build ID computations. GOARM = envOr("GOARM", fmt.Sprint(objabi.GOARM)) GO386 = envOr("GO386", objabi.GO386) - GOAMD64 = envOr("GOAMD64", objabi.GOAMD64) GOMIPS = envOr("GOMIPS", objabi.GOMIPS) GOMIPS64 = envOr("GOMIPS64", objabi.GOMIPS64) GOPPC64 = envOr("GOPPC64", fmt.Sprintf("%s%d", "power", objabi.GOPPC64)) @@ -267,8 +266,6 @@ func GetArchEnv() (key, val string) { return "GOARM", GOARM case "386": return "GO386", GO386 - case "amd64": - return "GOAMD64", GOAMD64 case "mips", "mipsle": return "GOMIPS", GOMIPS case "mips64", "mips64le": diff --git a/src/cmd/go/internal/help/helpdoc.go b/src/cmd/go/internal/help/helpdoc.go index 9583b3f327..693de8ff49 100644 --- a/src/cmd/go/internal/help/helpdoc.go +++ b/src/cmd/go/internal/help/helpdoc.go @@ -582,9 +582,6 @@ Architecture-specific environment variables: GO386 For GOARCH=386, the floating point instruction set. Valid values are 387, sse2. - GOAMD64 - For GOARCH=amd64, jumps can be optionally be aligned such that they do not end on - or cross 32 byte boundaries. Valid values are alignedjumps (default), normaljumps. GOMIPS For GOARCH=mips{,le}, whether to use floating point instructions. Valid values are hardfloat (default), softfloat. diff --git a/src/cmd/go/internal/modfetch/proxy.go b/src/cmd/go/internal/modfetch/proxy.go index 0ca43d4c4a..3971598733 100644 --- a/src/cmd/go/internal/modfetch/proxy.go +++ b/src/cmd/go/internal/modfetch/proxy.go @@ -196,8 +196,12 @@ func TryProxies(f func(proxy string) error) error { // We try to report the most helpful error to the user. "direct" and "noproxy" // errors are best, followed by proxy errors other than ErrNotExist, followed - // by ErrNotExist. Note that errProxyOff, errNoproxy, and errUseProxy are - // equivalent to ErrNotExist. + // by ErrNotExist. + // + // Note that errProxyOff, errNoproxy, and errUseProxy are equivalent to + // ErrNotExist. errUseProxy should only be returned if "noproxy" is the only + // proxy. errNoproxy should never be returned, since there should always be a + // more useful error from "noproxy" first. const ( notExistRank = iota proxyRank @@ -212,7 +216,7 @@ func TryProxies(f func(proxy string) error) error { } isNotExistErr := errors.Is(err, os.ErrNotExist) - if proxy.url == "direct" || proxy.url == "noproxy" { + if proxy.url == "direct" || (proxy.url == "noproxy" && err != errUseProxy) { bestErr = err bestErrRank = directRank } else if bestErrRank <= proxyRank && !isNotExistErr { diff --git a/src/cmd/go/internal/work/exec.go b/src/cmd/go/internal/work/exec.go index 6ab3498c3e..071c9d2db9 100644 --- a/src/cmd/go/internal/work/exec.go +++ b/src/cmd/go/internal/work/exec.go @@ -2434,13 +2434,25 @@ func (b *Builder) gccSupportsFlag(compiler []string, flag string) bool { if b.flagCache == nil { b.flagCache = make(map[[2]string]bool) } + + tmp := os.DevNull + if runtime.GOOS == "windows" { + f, err := ioutil.TempFile(b.WorkDir, "") + if err != nil { + return false + } + f.Close() + tmp = f.Name() + defer os.Remove(tmp) + } + // We used to write an empty C file, but that gets complicated with // go build -n. We tried using a file that does not exist, but that // fails on systems with GCC version 4.2.1; that is the last GPLv2 // version of GCC, so some systems have frozen on it. // Now we pass an empty file on stdin, which should work at least for // GCC and clang. - cmdArgs := str.StringList(compiler, flag, "-c", "-x", "c", "-", "-o", os.DevNull) + cmdArgs := str.StringList(compiler, flag, "-c", "-x", "c", "-", "-o", tmp) if cfg.BuildN || cfg.BuildX { b.Showcmd(b.WorkDir, "%s || true", joinUnambiguously(cmdArgs)) if cfg.BuildN { diff --git a/src/cmd/go/note_test.go b/src/cmd/go/note_test.go index 089e2f3376..659366dcf9 100644 --- a/src/cmd/go/note_test.go +++ b/src/cmd/go/note_test.go @@ -53,7 +53,7 @@ func TestNoteReading(t *testing.T) { // we've had trouble reading the notes generated by gold. err := tg.doRun([]string{"build", "-ldflags", "-buildid=" + buildID + " -linkmode=external -extldflags=-fuse-ld=gold", "-o", tg.path("hello3.exe"), tg.path("hello.go")}) if err != nil { - if tg.grepCountBoth("(invalid linker|gold|cannot find 'ld')") > 0 { + if tg.grepCountBoth("(invalid linker|gold|cannot find [‘']ld[’'])") > 0 { // It's not an error if gold isn't there. gcc claims it "cannot find 'ld'" if // ld.gold is missing, see issue #22340. t.Log("skipping gold test") diff --git a/src/cmd/go/testdata/script/issue36000.txt b/src/cmd/go/testdata/script/issue36000.txt new file mode 100644 index 0000000000..41732751ac --- /dev/null +++ b/src/cmd/go/testdata/script/issue36000.txt @@ -0,0 +1,6 @@ +# Tests golang.org/issue/36000 + +[!cgo] skip + +# go env with CGO flags should not make NUL file +go env CGO_CFLAGS diff --git a/src/cmd/go/testdata/script/mod_gonoproxy.txt b/src/cmd/go/testdata/script/mod_gonoproxy.txt index 2bd94cdee0..d7848c7d26 100644 --- a/src/cmd/go/testdata/script/mod_gonoproxy.txt +++ b/src/cmd/go/testdata/script/mod_gonoproxy.txt @@ -10,7 +10,7 @@ env GOSUMDB=$sumdb' '$proxy/sumdb-wrong ! go get rsc.io/quote stderr 'SECURITY ERROR' -# but GONOSUMDB bypasses sumdb, for rsc.io/quote, rsc.io/sampler, golang.org/x/text +# GONOSUMDB bypasses sumdb, for rsc.io/quote, rsc.io/sampler, golang.org/x/text env GONOSUMDB='*/quote,*/*mple*,golang.org/x' go get rsc.io/quote rm go.sum @@ -18,7 +18,13 @@ env GOPRIVATE='*/quote,*/*mple*,golang.org/x' env GONOPROXY=none # that is, proxy all despite GOPRIVATE go get rsc.io/quote -# and GONOPROXY bypasses proxy +# When GOPROXY=off, fetching modules not matched by GONOPROXY fails. +env GONOPROXY=*/fortune +env GOPROXY=off +! go get golang.org/x/text +stderr '^go get golang.org/x/text: module lookup disabled by GOPROXY=off$' + +# GONOPROXY bypasses proxy [!net] skip [!exec:git] skip env GOPRIVATE=none diff --git a/src/cmd/internal/obj/objfile.go b/src/cmd/internal/obj/objfile.go index 6701b9bfba..5e7018eb6e 100644 --- a/src/cmd/internal/obj/objfile.go +++ b/src/cmd/internal/obj/objfile.go @@ -425,6 +425,14 @@ func (ft *DwarfFixupTable) SetPrecursorFunc(s *LSym, fn interface{}) { absfn.Type = objabi.SDWARFINFO ft.ctxt.Data = append(ft.ctxt.Data, absfn) + // In the case of "late" inlining (inlines that happen during + // wrapper generation as opposed to the main inlining phase) it's + // possible that we didn't cache the abstract function sym for the + // text symbol -- do so now if needed. See issue 38068. + if s.Func != nil && s.Func.dwarfAbsFnSym == nil { + s.Func.dwarfAbsFnSym = absfn + } + ft.precursor[s] = fnState{precursor: fn, absfn: absfn} } diff --git a/src/cmd/internal/objabi/util.go b/src/cmd/internal/objabi/util.go index 72dd5856f8..2f94ec6a67 100644 --- a/src/cmd/internal/objabi/util.go +++ b/src/cmd/internal/objabi/util.go @@ -37,16 +37,13 @@ var ( const ( ElfRelocOffset = 256 - MachoRelocOffset = 2048 // reserve enough space for ELF relocations + MachoRelocOffset = 2048 // reserve enough space for ELF relocations + Go115AMD64 = "alignedjumps" // Should be "alignedjumps" or "normaljumps"; this replaces environment variable introduced in CL 219357. ) +// TODO(1.16): assuming no issues in 1.15 release, remove this and related constant. func goamd64() string { - switch v := envOr("GOAMD64", defaultGOAMD64); v { - case "normaljumps", "alignedjumps": - return v - } - log.Fatalf("Invalid GOAMD64 value. Must be normaljumps or alignedjumps.") - panic("unreachable") + return Go115AMD64 } func goarm() int { diff --git a/src/cmd/link/internal/arm/asm.go b/src/cmd/link/internal/arm/asm.go index 08f6c765c6..357a22b879 100644 --- a/src/cmd/link/internal/arm/asm.go +++ b/src/cmd/link/internal/arm/asm.go @@ -385,12 +385,16 @@ func trampoline(ctxt *ld.Link, ldr *loader.Loader, ri int, rs, s loader.Sym) { offset := (signext24(r.Add()&0xffffff) + 2) * 4 var tramp loader.Sym for i := 0; ; i++ { - name := ldr.SymName(rs) + fmt.Sprintf("%+d-tramp%d", offset, i) + oName := ldr.SymName(rs) + name := oName + fmt.Sprintf("%+d-tramp%d", offset, i) tramp = ldr.LookupOrCreateSym(name, int(ldr.SymVersion(rs))) if ldr.SymType(tramp) == sym.SDYNIMPORT { // don't reuse trampoline defined in other module continue } + if oName == "runtime.deferreturn" { + ldr.SetIsDeferReturnTramp(tramp, true) + } if ldr.SymValue(tramp) == 0 { // either the trampoline does not exist -- we need to create one, // or found one the address which is not assigned -- this will be diff --git a/src/cmd/link/internal/ld/fallocate_test.go b/src/cmd/link/internal/ld/fallocate_test.go new file mode 100644 index 0000000000..a064bea23d --- /dev/null +++ b/src/cmd/link/internal/ld/fallocate_test.go @@ -0,0 +1,50 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build darwin linux + +package ld + +import ( + "io/ioutil" + "os" + "path/filepath" + "syscall" + "testing" +) + +func TestFallocate(t *testing.T) { + dir, err := ioutil.TempDir("", "TestFallocate") + if err != nil { + t.Fatal(err) + } + defer os.RemoveAll(dir) + filename := filepath.Join(dir, "a.out") + out := NewOutBuf(nil) + err = out.Open(filename) + if err != nil { + t.Fatalf("Open file failed: %v", err) + } + defer out.Close() + + // Mmap 1 MiB initially, and grow to 2 and 3 MiB. + // Check if the file size and disk usage is expected. + for _, sz := range []int64{1 << 20, 2 << 20, 3 << 20} { + err = out.Mmap(uint64(sz)) + if err != nil { + t.Fatalf("Mmap failed: %v", err) + } + stat, err := os.Stat(filename) + if err != nil { + t.Fatalf("Stat failed: %v", err) + } + if got := stat.Size(); got != sz { + t.Errorf("unexpected file size: got %d, want %d", got, sz) + } + if got, want := stat.Sys().(*syscall.Stat_t).Blocks, (sz+511)/512; got != want { + t.Errorf("unexpected disk usage: got %d blocks, want %d", got, want) + } + out.munmap() + } +} diff --git a/src/cmd/link/internal/ld/outbuf_darwin.go b/src/cmd/link/internal/ld/outbuf_darwin.go index 299902ec62..9a74ba875e 100644 --- a/src/cmd/link/internal/ld/outbuf_darwin.go +++ b/src/cmd/link/internal/ld/outbuf_darwin.go @@ -10,16 +10,25 @@ import ( ) func (out *OutBuf) fallocate(size uint64) error { + stat, err := out.f.Stat() + if err != nil { + return err + } + cursize := uint64(stat.Size()) + if size <= cursize { + return nil + } + store := &syscall.Fstore_t{ Flags: syscall.F_ALLOCATEALL, Posmode: syscall.F_PEOFPOSMODE, Offset: 0, - Length: int64(size), + Length: int64(size - cursize), // F_PEOFPOSMODE allocates from the end of the file, so we want the size difference here } - _, _, err := syscall.Syscall(syscall.SYS_FCNTL, uintptr(out.f.Fd()), syscall.F_PREALLOCATE, uintptr(unsafe.Pointer(store))) - if err != 0 { - return err + _, _, errno := syscall.Syscall(syscall.SYS_FCNTL, uintptr(out.f.Fd()), syscall.F_PREALLOCATE, uintptr(unsafe.Pointer(store))) + if errno != 0 { + return errno } return nil diff --git a/src/cmd/link/internal/ld/pcln.go b/src/cmd/link/internal/ld/pcln.go index dc2fb70175..a5f776ebff 100644 --- a/src/cmd/link/internal/ld/pcln.go +++ b/src/cmd/link/internal/ld/pcln.go @@ -161,7 +161,7 @@ func (state *pclnState) computeDeferReturn(target *Target, s loader.Sym) uint32 // set the resumption point to PC_B. lastWasmAddr = uint32(r.Add()) } - if r.Type().IsDirectCall() && r.Sym() == state.deferReturnSym { + if r.Type().IsDirectCall() && (r.Sym() == state.deferReturnSym || state.ldr.IsDeferReturnTramp(r.Sym())) { if target.IsWasm() { deferreturn = lastWasmAddr - 1 } else { diff --git a/src/cmd/link/internal/loader/loader.go b/src/cmd/link/internal/loader/loader.go index b9e063288a..e340506978 100644 --- a/src/cmd/link/internal/loader/loader.go +++ b/src/cmd/link/internal/loader/loader.go @@ -229,7 +229,8 @@ type Loader struct { outdata [][]byte // symbol's data in the output buffer extRelocs [][]ExtReloc // symbol's external relocations - itablink map[Sym]struct{} // itablink[j] defined if j is go.itablink.* + itablink map[Sym]struct{} // itablink[j] defined if j is go.itablink.* + deferReturnTramp map[Sym]bool // whether the symbol is a trampoline of a deferreturn call objByPkg map[string]*oReader // map package path to its Go object reader @@ -354,6 +355,7 @@ func NewLoader(flags uint32, elfsetstring elfsetstringFunc, reporter *ErrorRepor attrCgoExportDynamic: make(map[Sym]struct{}), attrCgoExportStatic: make(map[Sym]struct{}), itablink: make(map[Sym]struct{}), + deferReturnTramp: make(map[Sym]bool), extStaticSyms: make(map[nameVer]Sym), builtinSyms: make([]Sym, nbuiltin), flags: flags, @@ -1050,6 +1052,16 @@ func (l *Loader) IsItabLink(i Sym) bool { return false } +// Return whether this is a trampoline of a deferreturn call. +func (l *Loader) IsDeferReturnTramp(i Sym) bool { + return l.deferReturnTramp[i] +} + +// Set that i is a trampoline of a deferreturn call. +func (l *Loader) SetIsDeferReturnTramp(i Sym, v bool) { + l.deferReturnTramp[i] = v +} + // growValues grows the slice used to store symbol values. func (l *Loader) growValues(reqLen int) { curLen := len(l.values) diff --git a/src/cmd/link/internal/ppc64/asm.go b/src/cmd/link/internal/ppc64/asm.go index ee14601caa..aae42c0bbc 100644 --- a/src/cmd/link/internal/ppc64/asm.go +++ b/src/cmd/link/internal/ppc64/asm.go @@ -686,16 +686,20 @@ func trampoline(ctxt *ld.Link, ldr *loader.Loader, ri int, rs, s loader.Sym) { // target is at some offset within the function. Calls to duff+8 and duff+256 must appear as // distinct trampolines. - name := ldr.SymName(rs) + oName := ldr.SymName(rs) + name := oName if r.Add() == 0 { - name = name + fmt.Sprintf("-tramp%d", i) + name += fmt.Sprintf("-tramp%d", i) } else { - name = name + fmt.Sprintf("%+x-tramp%d", r.Add(), i) + name += fmt.Sprintf("%+x-tramp%d", r.Add(), i) } // Look up the trampoline in case it already exists tramp = ldr.LookupOrCreateSym(name, int(ldr.SymVersion(rs))) + if oName == "runtime.deferreturn" { + ldr.SetIsDeferReturnTramp(tramp, true) + } if ldr.SymValue(tramp) == 0 { break } diff --git a/src/cmd/link/link_test.go b/src/cmd/link/link_test.go index 145eb3c4ae..635c55dce6 100644 --- a/src/cmd/link/link_test.go +++ b/src/cmd/link/link_test.go @@ -605,10 +605,23 @@ func TestFuncAlign(t *testing.T) { } } -const helloSrc = ` +const testTrampSrc = ` package main import "fmt" -func main() { fmt.Println("hello") } +func main() { + fmt.Println("hello") + + defer func(){ + if e := recover(); e == nil { + panic("did not panic") + } + }() + f1() +} + +// Test deferreturn trampolines. See issue #39049. +func f1() { defer f2() } +func f2() { panic("XXX") } ` func TestTrampoline(t *testing.T) { @@ -631,7 +644,7 @@ func TestTrampoline(t *testing.T) { defer os.RemoveAll(tmpdir) src := filepath.Join(tmpdir, "hello.go") - err = ioutil.WriteFile(src, []byte(helloSrc), 0666) + err = ioutil.WriteFile(src, []byte(testTrampSrc), 0666) if err != nil { t.Fatal(err) } diff --git a/src/cmd/vendor/modules.txt b/src/cmd/vendor/modules.txt index 0a3ea66ffd..8a7976a4bf 100644 --- a/src/cmd/vendor/modules.txt +++ b/src/cmd/vendor/modules.txt @@ -29,7 +29,7 @@ golang.org/x/arch/x86/x86asm golang.org/x/crypto/ed25519 golang.org/x/crypto/ed25519/internal/edwards25519 golang.org/x/crypto/ssh/terminal -# golang.org/x/mod v0.2.1-0.20200429172858-859b3ef565e2 +# golang.org/x/mod v0.3.0 ## explicit golang.org/x/mod/internal/lazyregexp golang.org/x/mod/modfile |
