From c7491d0d09cb221dd8968e984f387bc299bb7b6f Mon Sep 17 00:00:00 2001 From: Hiroaki Nakamura Date: Fri, 16 Aug 2019 09:30:30 +0900 Subject: [PATCH] New upstream version 1.12.9 --- VERSION | 2 +- doc/devel/release.html | 7 ++ doc/go1.12.html | 4 + misc/cgo/testshared/shared_test.go | 7 ++ .../src/issue30768/issue30768lib/lib.go | 11 ++ misc/cgo/testshared/src/issue30768/x_test.go | 22 ++++ src/cmd/link/internal/ld/lib.go | 14 ++- src/crypto/tls/tls_test.go | 41 ------- src/math/big/arith_arm64.s | 102 ++++++++++-------- src/math/big/arith_test.go | 69 ++++++++++++ src/os/removeall_at.go | 2 +- test/fixedbugs/issue33555.go | 81 ++++++++++++++ 12 files changed, 273 insertions(+), 89 deletions(-) create mode 100644 misc/cgo/testshared/src/issue30768/issue30768lib/lib.go create mode 100644 misc/cgo/testshared/src/issue30768/x_test.go create mode 100644 test/fixedbugs/issue33555.go diff --git a/VERSION b/VERSION index a62d1ea3..486d1f31 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -go1.12.8 \ No newline at end of file +go1.12.9 \ No newline at end of file diff --git a/doc/devel/release.html b/doc/devel/release.html index 1bb3730d..437e3c60 100644 --- a/doc/devel/release.html +++ b/doc/devel/release.html @@ -91,6 +91,13 @@

Minor revisions

1.12.8 milestone on our issue tracker for details.

+

+go1.12.9 (released 2019/08/15) includes fixes to the linker, +and the os and math/big packages. +See the Go +1.12.9 milestone on our issue tracker for details. +

+

go1.11 (released 2018/08/24)

diff --git a/doc/go1.12.html b/doc/go1.12.html index cc19c0f3..7f0b221c 100644 --- a/doc/go1.12.html +++ b/doc/go1.12.html @@ -80,6 +80,10 @@

Darwin

checks for private API usage. Since it is considered private, syscall.Getdirentries now always fails with ENOSYS on iOS. + Additionally, syscall.Setrlimit + reports invalid argument in places where it historically + succeeded. These consequences are not specific to Go and users should expect + behavioral parity with libSystem's implementation going forward.

Tools

diff --git a/misc/cgo/testshared/shared_test.go b/misc/cgo/testshared/shared_test.go index 41a24efe..1f426bb9 100644 --- a/misc/cgo/testshared/shared_test.go +++ b/misc/cgo/testshared/shared_test.go @@ -917,3 +917,10 @@ func TestTestInstalledShared(t *testing.T) { func TestGeneratedMethod(t *testing.T) { goCmd(t, "install", "-buildmode=shared", "-linkshared", "issue25065") } + +// Test use of shared library struct with generated hash function. +// Issue 30768. +func TestGeneratedHash(t *testing.T) { + goCmd(nil, "install", "-buildmode=shared", "-linkshared", "issue30768/issue30768lib") + goCmd(nil, "test", "-linkshared", "issue30768") +} diff --git a/misc/cgo/testshared/src/issue30768/issue30768lib/lib.go b/misc/cgo/testshared/src/issue30768/issue30768lib/lib.go new file mode 100644 index 00000000..9e45ebe6 --- /dev/null +++ b/misc/cgo/testshared/src/issue30768/issue30768lib/lib.go @@ -0,0 +1,11 @@ +// Copyright 2019 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. + +package issue30768lib + +// S is a struct that requires a generated hash function. +type S struct { + A string + B int +} diff --git a/misc/cgo/testshared/src/issue30768/x_test.go b/misc/cgo/testshared/src/issue30768/x_test.go new file mode 100644 index 00000000..228da6f6 --- /dev/null +++ b/misc/cgo/testshared/src/issue30768/x_test.go @@ -0,0 +1,22 @@ +// Copyright 2019 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. + +package issue30768_test + +import ( + "testing" + + "issue30768/issue30768lib" +) + +type s struct { + s issue30768lib.S +} + +func Test30768(t *testing.T) { + // Calling t.Log will convert S to an empty interface, + // which will force a reference to the generated hash function, + // defined in the shared library. + t.Log(s{}) +} diff --git a/src/cmd/link/internal/ld/lib.go b/src/cmd/link/internal/ld/lib.go index 2cb7ae72..e63cf716 100644 --- a/src/cmd/link/internal/ld/lib.go +++ b/src/cmd/link/internal/ld/lib.go @@ -1802,7 +1802,15 @@ func ldshlibsyms(ctxt *Link, shlib string) { if elf.ST_TYPE(elfsym.Info) == elf.STT_NOTYPE || elf.ST_TYPE(elfsym.Info) == elf.STT_SECTION { continue } - lsym := ctxt.Syms.Lookup(elfsym.Name, 0) + + // Symbols whose names start with "type." are compiler + // generated, so make functions with that prefix internal. + ver := 0 + if elf.ST_TYPE(elfsym.Info) == elf.STT_FUNC && strings.HasPrefix(elfsym.Name, "type.") { + ver = sym.SymVerABIInternal + } + + lsym := ctxt.Syms.Lookup(elfsym.Name, ver) // Because loadlib above loads all .a files before loading any shared // libraries, any non-dynimport symbols we find that duplicate symbols // already loaded should be ignored (the symbols from the .a files @@ -1830,7 +1838,7 @@ func ldshlibsyms(ctxt *Link, shlib string) { // the ABIs are actually different. We might have to // mangle Go function names in the .so to include the // ABI. - if elf.ST_TYPE(elfsym.Info) == elf.STT_FUNC { + if elf.ST_TYPE(elfsym.Info) == elf.STT_FUNC && ver == 0 { alias := ctxt.Syms.Lookup(elfsym.Name, sym.SymVerABIInternal) if alias.Type != 0 { continue @@ -1958,7 +1966,7 @@ func stkcheck(ctxt *Link, up *chain, depth int) int { s.Attr |= sym.AttrStackCheck } - if depth > 100 { + if depth > 500 { Errorf(s, "nosplit stack check too deep") stkbroke(ctxt, up, 0) return -1 diff --git a/src/crypto/tls/tls_test.go b/src/crypto/tls/tls_test.go index 208c13c1..d7d1e2c0 100644 --- a/src/crypto/tls/tls_test.go +++ b/src/crypto/tls/tls_test.go @@ -370,47 +370,6 @@ func TestVerifyHostname(t *testing.T) { } } -func TestVerifyHostnameResumed(t *testing.T) { - t.Run("TLSv12", func(t *testing.T) { testVerifyHostnameResumed(t, VersionTLS12) }) - t.Run("TLSv13", func(t *testing.T) { testVerifyHostnameResumed(t, VersionTLS13) }) -} - -func testVerifyHostnameResumed(t *testing.T, version uint16) { - testenv.MustHaveExternalNetwork(t) - - config := &Config{ - MaxVersion: version, - ClientSessionCache: NewLRUClientSessionCache(32), - } - for i := 0; i < 2; i++ { - c, err := Dial("tcp", "mail.google.com:https", config) - if err != nil { - t.Fatalf("Dial #%d: %v", i, err) - } - cs := c.ConnectionState() - if i > 0 && !cs.DidResume { - t.Fatalf("Subsequent connection unexpectedly didn't resume") - } - if cs.Version != version { - t.Fatalf("Unexpectedly negotiated version %x", cs.Version) - } - if cs.VerifiedChains == nil { - t.Fatalf("Dial #%d: cs.VerifiedChains == nil", i) - } - if err := c.VerifyHostname("mail.google.com"); err != nil { - t.Fatalf("verify mail.google.com #%d: %v", i, err) - } - // Give the client a chance to read the server session tickets. - c.SetReadDeadline(time.Now().Add(500 * time.Millisecond)) - if _, err := c.Read(make([]byte, 1)); err != nil { - if err, ok := err.(net.Error); !ok || !err.Timeout() { - t.Fatal(err) - } - } - c.Close() - } -} - func TestConnCloseBreakingWrite(t *testing.T) { ln := newLocalListener(t) defer ln.Close() diff --git a/src/math/big/arith_arm64.s b/src/math/big/arith_arm64.s index eebdf59f..98bdbc76 100644 --- a/src/math/big/arith_arm64.s +++ b/src/math/big/arith_arm64.s @@ -194,83 +194,97 @@ len0: MOVD R2, c+56(FP) RET - // func shlVU(z, x []Word, s uint) (c Word) +// This implementation handles the shift operation from the high word to the low word, +// which may be an error for the case where the low word of x overlaps with the high +// word of z. When calling this function directly, you need to pay attention to this +// situation. TEXT ·shlVU(SB),NOSPLIT,$0 - MOVD z+0(FP), R0 - MOVD z_len+8(FP), R1 + LDP z+0(FP), (R0, R1) // R0 = z.ptr, R1 = len(z) MOVD x+24(FP), R2 MOVD s+48(FP), R3 - MOVD $0, R8 // in order not to affect the first element, R8 is initialized to zero - MOVD $64, R4 - SUB R3, R4 + ADD R1<<3, R0 // R0 = &z[n] + ADD R1<<3, R2 // R2 = &x[n] CBZ R1, len0 CBZ R3, copy // if the number of shift is 0, just copy x to z - - TBZ $0, R1, two - MOVD.P 8(R2), R6 - LSR R4, R6, R8 - LSL R3, R6 - MOVD.P R6, 8(R0) + MOVD $64, R4 + SUB R3, R4 + // handling the most significant element x[n-1] + MOVD.W -8(R2), R6 + LSR R4, R6, R5 // return value + LSL R3, R6, R8 // x[i] << s + SUB $1, R1 +one: TBZ $0, R1, two + MOVD.W -8(R2), R6 + LSR R4, R6, R7 + ORR R8, R7 + LSL R3, R6, R8 SUB $1, R1 + MOVD.W R7, -8(R0) two: TBZ $1, R1, loop - LDP.P 16(R2), (R6, R7) - LSR R4, R6, R9 - LSL R3, R6 - ORR R8, R6 - LSR R4, R7, R8 + LDP.W -16(R2), (R6, R7) + LSR R4, R7, R10 + ORR R8, R10 LSL R3, R7 - ORR R9, R7 - STP.P (R6, R7), 16(R0) + LSR R4, R6, R9 + ORR R7, R9 + LSL R3, R6, R8 SUB $2, R1 + STP.W (R9, R10), -16(R0) loop: CBZ R1, done - LDP.P 32(R2), (R10, R11) - LDP -16(R2), (R12, R13) - LSR R4, R10, R20 - LSL R3, R10 - ORR R8, R10 // z[i] = (x[i] << s) | (x[i-1] >> (64 - s)) - LSR R4, R11, R21 - LSL R3, R11 - ORR R20, R11 + LDP.W -32(R2), (R10, R11) + LDP 16(R2), (R12, R13) + LSR R4, R13, R23 + ORR R8, R23 // z[i] = (x[i] << s) | (x[i-1] >> (64 - s)) + LSL R3, R13 LSR R4, R12, R22 + ORR R13, R22 LSL R3, R12 - ORR R21, R12 - LSR R4, R13, R8 - LSL R3, R13 - ORR R22, R13 - STP.P (R10, R11), 32(R0) - STP (R12, R13), -16(R0) + LSR R4, R11, R21 + ORR R12, R21 + LSL R3, R11 + LSR R4, R10, R20 + ORR R11, R20 + LSL R3, R10, R8 + STP.W (R20, R21), -32(R0) + STP (R22, R23), 16(R0) SUB $4, R1 B loop done: - MOVD R8, c+56(FP) // the part moved out from the last element + MOVD.W R8, -8(R0) // the first element x[0] + MOVD R5, c+56(FP) // the part moved out from x[n-1] RET copy: + CMP R0, R2 + BEQ len0 TBZ $0, R1, ctwo - MOVD.P 8(R2), R3 - MOVD.P R3, 8(R0) + MOVD.W -8(R2), R4 + MOVD.W R4, -8(R0) SUB $1, R1 ctwo: TBZ $1, R1, cloop - LDP.P 16(R2), (R4, R5) - STP.P (R4, R5), 16(R0) + LDP.W -16(R2), (R4, R5) + STP.W (R4, R5), -16(R0) SUB $2, R1 cloop: CBZ R1, len0 - LDP.P 32(R2), (R4, R5) - LDP -16(R2), (R6, R7) - STP.P (R4, R5), 32(R0) - STP (R6, R7), -16(R0) + LDP.W -32(R2), (R4, R5) + LDP 16(R2), (R6, R7) + STP.W (R4, R5), -32(R0) + STP (R6, R7), 16(R0) SUB $4, R1 B cloop len0: MOVD $0, c+56(FP) RET - // func shrVU(z, x []Word, s uint) (c Word) +// This implementation handles the shift operation from the low word to the high word, +// which may be an error for the case where the high word of x overlaps with the low +// word of z. When calling this function directly, you need to pay attention to this +// situation. TEXT ·shrVU(SB),NOSPLIT,$0 MOVD z+0(FP), R0 MOVD z_len+8(FP), R1 @@ -330,6 +344,8 @@ done: MOVD R8, (R0) // deal with the last element RET copy: + CMP R0, R2 + BEQ len0 TBZ $0, R1, ctwo MOVD.P 8(R2), R3 MOVD.P R3, 8(R0) diff --git a/src/math/big/arith_test.go b/src/math/big/arith_test.go index cf386b3b..d812f75d 100644 --- a/src/math/big/arith_test.go +++ b/src/math/big/arith_test.go @@ -255,6 +255,75 @@ func TestFunVW(t *testing.T) { } } +type argVU struct { + d []Word // d is a Word slice, the input parameters x and z come from this array. + l uint // l is the length of the input parameters x and z. + xp uint // xp is the starting position of the input parameter x, x := d[xp:xp+l]. + zp uint // zp is the starting position of the input parameter z, z := d[zp:zp+l]. + s uint // s is the shift number. + r []Word // r is the expected output result z. + c Word // c is the expected return value. + m string // message. +} + +var argshlVU = []argVU{ + // test cases for shlVU + {[]Word{1, _M, _M, _M, _M, _M, 3 << (_W - 2), 0}, 7, 0, 0, 1, []Word{2, _M - 1, _M, _M, _M, _M, 1<<(_W-1) + 1}, 1, "complete overlap of shlVU"}, + {[]Word{1, _M, _M, _M, _M, _M, 3 << (_W - 2), 0, 0, 0, 0}, 7, 0, 3, 1, []Word{2, _M - 1, _M, _M, _M, _M, 1<<(_W-1) + 1}, 1, "partial overlap by half of shlVU"}, + {[]Word{1, _M, _M, _M, _M, _M, 3 << (_W - 2), 0, 0, 0, 0, 0, 0, 0}, 7, 0, 6, 1, []Word{2, _M - 1, _M, _M, _M, _M, 1<<(_W-1) + 1}, 1, "partial overlap by 1 Word of shlVU"}, + {[]Word{1, _M, _M, _M, _M, _M, 3 << (_W - 2), 0, 0, 0, 0, 0, 0, 0, 0}, 7, 0, 7, 1, []Word{2, _M - 1, _M, _M, _M, _M, 1<<(_W-1) + 1}, 1, "no overlap of shlVU"}, +} + +var argshrVU = []argVU{ + // test cases for shrVU + {[]Word{0, 3, _M, _M, _M, _M, _M, 1 << (_W - 1)}, 7, 1, 1, 1, []Word{1<<(_W-1) + 1, _M, _M, _M, _M, _M >> 1, 1 << (_W - 2)}, 1 << (_W - 1), "complete overlap of shrVU"}, + {[]Word{0, 0, 0, 0, 3, _M, _M, _M, _M, _M, 1 << (_W - 1)}, 7, 4, 1, 1, []Word{1<<(_W-1) + 1, _M, _M, _M, _M, _M >> 1, 1 << (_W - 2)}, 1 << (_W - 1), "partial overlap by half of shrVU"}, + {[]Word{0, 0, 0, 0, 0, 0, 0, 3, _M, _M, _M, _M, _M, 1 << (_W - 1)}, 7, 7, 1, 1, []Word{1<<(_W-1) + 1, _M, _M, _M, _M, _M >> 1, 1 << (_W - 2)}, 1 << (_W - 1), "partial overlap by 1 Word of shrVU"}, + {[]Word{0, 0, 0, 0, 0, 0, 0, 0, 3, _M, _M, _M, _M, _M, 1 << (_W - 1)}, 7, 8, 1, 1, []Word{1<<(_W-1) + 1, _M, _M, _M, _M, _M >> 1, 1 << (_W - 2)}, 1 << (_W - 1), "no overlap of shrVU"}, +} + +func testShiftFunc(t *testing.T, f func(z, x []Word, s uint) Word, a argVU) { + // save a.d for error message, or it will be overwritten. + b := make([]Word, len(a.d)) + copy(b, a.d) + z := a.d[a.zp : a.zp+a.l] + x := a.d[a.xp : a.xp+a.l] + c := f(z, x, a.s) + for i, zi := range z { + if zi != a.r[i] { + t.Errorf("d := %v, %s(d[%d:%d], d[%d:%d], %d)\n\tgot z[%d] = %#x; want %#x", b, a.m, a.zp, a.zp+a.l, a.xp, a.xp+a.l, a.s, i, zi, a.r[i]) + break + } + } + if c != a.c { + t.Errorf("d := %v, %s(d[%d:%d], d[%d:%d], %d)\n\tgot c = %#x; want %#x", b, a.m, a.zp, a.zp+a.l, a.xp, a.xp+a.l, a.s, c, a.c) + } +} + +func TestShiftOverlap(t *testing.T) { + for _, a := range argshlVU { + arg := a + testShiftFunc(t, shlVU, arg) + } + + for _, a := range argshrVU { + arg := a + testShiftFunc(t, shrVU, arg) + } +} + +func TestIssue31084(t *testing.T) { + // compute 10^n via 5^n << n. + const n = 165 + p := nat(nil).expNN(nat{5}, nat{n}, nil) + p = p.shl(p, uint(n)) + got := string(p.utoa(10)) + want := "1" + strings.Repeat("0", n) + if got != want { + t.Errorf("shl(%v, %v)\n\tgot %s; want %s\n", p, uint(n), got, want) + } +} + func BenchmarkAddVW(b *testing.B) { for _, n := range benchSizes { if isRaceBuilder && n > 1e3 { diff --git a/src/os/removeall_at.go b/src/os/removeall_at.go index 330963b3..c7de8a32 100644 --- a/src/os/removeall_at.go +++ b/src/os/removeall_at.go @@ -157,7 +157,7 @@ func openFdAt(dirfd int, name string) (*File, error) { var r int for { var e error - r, e = unix.Openat(dirfd, name, O_RDONLY, 0) + r, e = unix.Openat(dirfd, name, O_RDONLY|syscall.O_CLOEXEC, 0) if e == nil { break } diff --git a/test/fixedbugs/issue33555.go b/test/fixedbugs/issue33555.go new file mode 100644 index 00000000..7debd204 --- /dev/null +++ b/test/fixedbugs/issue33555.go @@ -0,0 +1,81 @@ +// +build !nacl,!js +// run + +// Copyright 2019 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. + +// Test that the linker permits long call sequences. +package main + +import ( + "bytes" + "fmt" + "io/ioutil" + "os" + "os/exec" + "path/filepath" + "strconv" +) + +const start = ` +package main + +func main() { + println(f0() + 1) +} +` + +const fn = ` +//go:noinline +func f%d() int { + return f%d() + 1 +}` + +const fnlast = ` +//go:noinline +func f%d() int { + return 0 +} +` + +const count = 400 + +func main() { + if err := test(); err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } +} + +func test() error { + var buf bytes.Buffer + buf.WriteString(start) + for i := 0; i < count; i++ { + fmt.Fprintf(&buf, fn, i, i + 1) + } + fmt.Fprintf(&buf, fnlast, count) + + dir, err := ioutil.TempDir("", "issue33555") + if err != nil { + return err + } + defer os.RemoveAll(dir) + + fn := filepath.Join(dir, "x.go") + if err := ioutil.WriteFile(fn, buf.Bytes(), 0644); err != nil { + return err + } + + out, err := exec.Command("go", "run", fn).CombinedOutput() + if err != nil { + return err + } + + want := strconv.Itoa(count + 1) + if got := string(bytes.TrimSpace(out)); got != want { + return fmt.Errorf("got %q want %q", got, want) + } + + return nil +}