aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFilippo Valsorda <filippo@golang.org>2019-08-20 14:58:17 -0400
committerFilippo Valsorda <filippo@golang.org>2019-08-20 14:58:17 -0400
commitee88e5b118b55d82f61c0892243d3311469fbe51 (patch)
treeaab8288a01f0ef7d2337e5e474e6b95293fa4326
parent55186ba70c1a9d07930ae41c1afc93145345da91 (diff)
parent06472b99cdf59f00049f3cd8c9e05ba283cb2c56 (diff)
downloadgo-ee88e5b118b55d82f61c0892243d3311469fbe51.tar.gz
go-ee88e5b118b55d82f61c0892243d3311469fbe51.zip
[dev.boringcrypto.go1.12] all: merge go1.12.9 into dev.boringcrypto.go1.12
Change-Id: Ib50ec8a5ec235570ff1483f393acab48c45af585
-rw-r--r--doc/devel/release.html7
-rw-r--r--doc/go1.12.html4
-rw-r--r--misc/cgo/testshared/shared_test.go7
-rw-r--r--misc/cgo/testshared/src/issue30768/issue30768lib/lib.go11
-rw-r--r--misc/cgo/testshared/src/issue30768/x_test.go22
-rw-r--r--src/cmd/link/internal/ld/lib.go14
-rw-r--r--src/crypto/tls/tls_test.go41
-rw-r--r--src/math/big/arith_arm64.s102
-rw-r--r--src/math/big/arith_test.go69
-rw-r--r--src/os/removeall_at.go2
-rw-r--r--test/fixedbugs/issue33555.go81
11 files changed, 272 insertions, 88 deletions
diff --git a/doc/devel/release.html b/doc/devel/release.html
index 1bb3730d8b..437e3c60a4 100644
--- a/doc/devel/release.html
+++ b/doc/devel/release.html
@@ -91,6 +91,13 @@ See the <a href="https://github.com/golang/go/issues?q=milestone%3AGo1.12.8">Go
1.12.8 milestone</a> on our issue tracker for details.
</p>
+<p>
+go1.12.9 (released 2019/08/15) includes fixes to the linker,
+and the <code>os</code> and <code>math/big</code> packages.
+See the <a href="https://github.com/golang/go/issues?q=milestone%3AGo1.12.9+label%3ACherryPickApproved">Go
+1.12.9 milestone</a> on our issue tracker for details.
+</p>
+
<h2 id="go1.11">go1.11 (released 2018/08/24)</h2>
<p>
diff --git a/doc/go1.12.html b/doc/go1.12.html
index cc19c0f31a..7f0b221cc3 100644
--- a/doc/go1.12.html
+++ b/doc/go1.12.html
@@ -80,6 +80,10 @@ Do not send CLs removing the interior tags from such phrases.
checks for private API usage. Since it is considered private,
<code>syscall.Getdirentries</code> now always fails with
<code>ENOSYS</code> on iOS.
+ Additionally, <a href="/pkg/syscall/#Setrlimit"><code>syscall.Setrlimit</code></a>
+ reports <code>invalid</code> <code>argument</code> in places where it historically
+ succeeded. These consequences are not specific to Go and users should expect
+ behavioral parity with <code>libSystem</code>'s implementation going forward.
</p>
<h2 id="tools">Tools</h2>
diff --git a/misc/cgo/testshared/shared_test.go b/misc/cgo/testshared/shared_test.go
index 41a24efe22..1f426bb90b 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 0000000000..9e45ebe683
--- /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 0000000000..228da6f602
--- /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 91673a8d4d..c75c2942d3 100644
--- a/src/cmd/link/internal/ld/lib.go
+++ b/src/cmd/link/internal/ld/lib.go
@@ -1803,7 +1803,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
@@ -1831,7 +1839,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
@@ -1959,7 +1967,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 61f4eaf1ae..327a8dea27 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 eebdf59fb2..98bdbc76f9 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 cf386b3b38..d812f75de7 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 330963b354..c7de8a32a8 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 0000000000..7debd2049c
--- /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
+}