diff --git a/doc/go1.16.html b/doc/go1.16.html index 92cadff713..6e371b9617 100644 --- a/doc/go1.16.html +++ b/doc/go1.16.html @@ -33,7 +33,7 @@ Do not send CLs removing the interior tags from such phrases.

Darwin

-

+

Go 1.16 adds support of 64-bit ARM architecture on macOS (also known as Apple Silicon) with GOOS=darwin, GOARCH=arm64. Like the darwin/amd64 port, the darwin/arm64 @@ -42,7 +42,7 @@ Do not send CLs removing the interior tags from such phrases. detector.

-

+

The iOS port, which was previously darwin/arm64, is now moved to ios/arm64. GOOS=ios implies the darwin build tag, just as GOOS=android @@ -80,6 +80,15 @@ Do not send CLs removing the interior tags from such phrases.

Go command

+

+ TODO + + + + + +

+

Modules

@@ -207,7 +216,7 @@ Do not send CLs removing the interior tags from such phrases.

Cgo

-

+

The cgo tool will no longer try to translate C struct bitfields into Go struct fields, even if their size can be represented in Go. The order in which C bitfields appear in memory @@ -215,8 +224,12 @@ Do not send CLs removing the interior tags from such phrases. results that were silently incorrect.

+

Vet

+

TODO + +

Runtime

@@ -245,7 +258,7 @@ Do not send CLs removing the interior tags from such phrases.

Linker

-

+

This release includes additional improvements to the Go linker, reducing linker resource usage (both time and memory) and improving code robustness/maintainability. These changes form the second half @@ -268,7 +281,7 @@ Do not send CLs removing the interior tags from such phrases. TODO: update with final numbers later in the release.

-

+

On Windows, go build -buildmode=c-shared now generates Windows ASLR DLLs by default. ASLR can be disabled with --ldflags=-aslr=false.

@@ -276,135 +289,13 @@ Do not send CLs removing the interior tags from such phrases.

Core library

- TODO + TODO: mention significant additions like new packages (io/fs), + new proposal-scoped features (//go:embed), and so on

-

crypto/hmac

- -

- New will now panic if separate calls to - the hash generation function fail to return new values. Previously, the - behavior was undefined and invalid outputs were sometimes generated. -

- -

crypto/tls

- -

- I/O operations on closing or closed TLS connections can now be detected using - the new ErrClosed error. A typical use - would be errors.Is(err, net.ErrClosed). In earlier releases - the only way to reliably detect this case was to match the string returned - by the Error method with "tls: use of closed connection". -

- -

- A default deadline is set in Close - before sending the close notify alert, in order to prevent blocking - indefinitely. -

- -

- (*Conn).HandshakeContext was added to - allow the user to control cancellation of an in-progress TLS Handshake. - The context provided is propagated into the - ClientHelloInfo - and CertificateRequestInfo - structs and accessible through the new - (*ClientHelloInfo).Context - and - - (*CertificateRequestInfo).Context - methods respectively. Canceling the context after the handshake has finished - has no effect. -

- -

- Clients now ensure that the server selects - - an ALPN protocol from - - the list advertised by the client. -

- -

- TLS servers will now prefer other AEAD cipher suites (such as ChaCha20Poly1305) - over AES-GCM cipher suites if either the client or server doesn't have AES hardware - support, unless the application set both - Config.PreferServerCipherSuites - and Config.CipherSuites - or there are no other AEAD cipher suites supported. - The client is assumed not to have AES hardware support if it does not signal a - preference for AES-GCM cipher suites. -

- -

crypto/x509

- -

- ParseCertificate and - CreateCertificate both - now enforce string encoding restrictions for the fields DNSNames, - EmailAddresses, and URIs. These fields can only - contain strings with characters within the ASCII range. -

- -

- CreateCertificate now - verifies the generated certificate's signature using the signer's - public key. If the signature is invalid, an error is returned, instead - of a malformed certificate. -

- -

- A number of additional fields have been added to the - CertificateRequest type. - These fields are now parsed in ParseCertificateRequest - and marshalled in CreateCertificateRequest. -

- -

encoding/json

- -

- The error message for - SyntaxError - now begins with "json: ", matching the other errors in the package. -

- -

net

- -

- The case of I/O on a closed network connection, or I/O on a network - connection that is closed before any of the I/O completes, can now - be detected using the new ErrClosed error. - A typical use would be errors.Is(err, net.ErrClosed). - In earlier releases the only way to reliably detect this case was to - match the string returned by the Error method - with "use of closed network connection". -

- -

- In previous Go releases the default TCP listener backlog size on Linux systems, - set by /proc/sys/net/core/somaxconn, was limited to a maximum of 65535. - On Linux kernel version 4.1 and above, the maximum is now 4294967295. -

- -

text/template/parse

- -

- A new CommentNode - was added to the parse tree. The Mode - field in the parse.Tree enables access to it. -

- - -

unicode

- -

- The unicode package and associated - support throughout the system has been upgraded from Unicode 12.0.0 to - Unicode 13.0.0, - which adds 5,930 new characters, including four new scripts, and 55 new emoji. - Unicode 13.0.0 also designates plane 3 (U+30000-U+3FFFF) as the tertiary - ideographic plane. +

+ TODO: when the "Minor changes to the library" section is close to completion, + decide if any changes are worth factoring out and highlighting in "Core library"

Minor changes to the library

@@ -416,7 +307,7 @@ Do not send CLs removing the interior tags from such phrases.

- TODO + TODO: complete this section, resolve TODOs below, add missing entries

crypto/dsa
@@ -428,16 +319,126 @@ Do not send CLs removing the interior tags from such phrases.
+
crypto/hmac
+
+

+ New will now panic if separate calls to + the hash generation function fail to return new values. Previously, the + behavior was undefined and invalid outputs were sometimes generated. +

+
+
+ +
crypto/tls
+
+

+ I/O operations on closing or closed TLS connections can now be detected using + the new ErrClosed error. A typical use + would be errors.Is(err, net.ErrClosed). In earlier releases + the only way to reliably detect this case was to match the string returned + by the Error method with "tls: use of closed connection". +

+ +

+ A default deadline is set in Close + before sending the close notify alert, in order to prevent blocking + indefinitely. +

+ +

+ (*Conn).HandshakeContext was added to + allow the user to control cancellation of an in-progress TLS Handshake. + The context provided is propagated into the + ClientHelloInfo + and CertificateRequestInfo + structs and accessible through the new + (*ClientHelloInfo).Context + and + + (*CertificateRequestInfo).Context + methods respectively. Canceling the context after the handshake has finished + has no effect. +

+ +

+ Clients now ensure that the server selects + + an ALPN protocol from + + the list advertised by the client. +

+ +

+ TLS servers will now prefer other AEAD cipher suites (such as ChaCha20Poly1305) + over AES-GCM cipher suites if either the client or server doesn't have AES hardware + support, unless the application set both + Config.PreferServerCipherSuites + and Config.CipherSuites + or there are no other AEAD cipher suites supported. + The client is assumed not to have AES hardware support if it does not signal a + preference for AES-GCM cipher suites. +

+ +

+ TODO: https://golang.org/cl/246637: make config.Clone return nil if the source is nil +

+
+
+
crypto/x509
+

+ ParseCertificate and + CreateCertificate both + now enforce string encoding restrictions for the fields DNSNames, + EmailAddresses, and URIs. These fields can only + contain strings with characters within the ASCII range. +

+ +

+ CreateCertificate now + verifies the generated certificate's signature using the signer's + public key. If the signature is invalid, an error is returned, instead + of a malformed certificate. +

+ +

+ A number of additional fields have been added to the + CertificateRequest type. + These fields are now parsed in ParseCertificateRequest + and marshalled in CreateCertificateRequest. +

+

DSA signature verification is no longer supported. Note that DSA signature generation was never supported. See issue #40337.

+ +

+ TODO: https://golang.org/cl/257257: return additional chains from Verify on Windows +

+ +

+ TODO: https://golang.org/cl/262343: add Unwrap to SystemRootsError +

+
encoding/json
+
+

+ The error message for + SyntaxError + now begins with "json: ", matching the other errors in the package. +

+ +

+ TODO: https://golang.org/cl/234818: allow semicolon in field key / struct tag +

+
+
+
encoding/xml

@@ -452,6 +453,70 @@ Do not send CLs removing the interior tags from such phrases.

+
flag
+
+

+ TODO: https://golang.org/cl/240014: add Func +

+
+
+ +
io
+
+

+ TODO: https://golang.org/cl/261577: add a new ReadSeekCloser interface +

+
+
+ +
log
+
+

+ TODO: https://golang.org/cl/264460: expose std via new Default function +

+
+
+ +
log/syslog
+
+

+ TODO: https://golang.org/cl/264297: set local to true if network is any of "unix", or "unixgram" +

+
+
+ +
mime/multipart
+
+

+ TODO: https://golang.org/cl/247477: return overflow errors in Reader.ReadForm +

+
+
+ +
net
+
+

+ The case of I/O on a closed network connection, or I/O on a network + connection that is closed before any of the I/O completes, can now + be detected using the new ErrClosed error. + A typical use would be errors.Is(err, net.ErrClosed). + In earlier releases the only way to reliably detect this case was to + match the string returned by the Error method + with "use of closed network connection". +

+ +

+ In previous Go releases the default TCP listener backlog size on Linux systems, + set by /proc/sys/net/core/somaxconn, was limited to a maximum of 65535. + On Linux kernel version 4.1 and above, the maximum is now 4294967295. +

+ +

+ TODO: https://golang.org/cl/238629: prefer /etc/hosts over DNS when no /etc/nsswitch.conf is present +

+
+
+
net/http

@@ -469,14 +534,14 @@ Do not send CLs removing the interior tags from such phrases.

- The net/http package now rejects HTTP range requests - of the form "Range": "bytes=--N" where "-N" is a negative suffix length, for - example "Range": "bytes=--2". It now replies with a 416 "Range Not Satisfiable" response. + The net/http package now rejects HTTP range requests + of the form "Range": "bytes=--N" where "-N" is a negative suffix length, for + example "Range": "bytes=--2". It now replies with a 416 "Range Not Satisfiable" response.

- Cookies set with SameSiteDefaultMode now behave according to the current - spec (no attribute is set) instead of generating a SameSite key without a value. + Cookies set with SameSiteDefaultMode now behave according to the current + spec (no attribute is set) instead of generating a SameSite key without a value.

@@ -485,9 +550,89 @@ Do not send CLs removing the interior tags from such phrases. with the Request context when performing TLS handshakes in the client or server.

+ +

+ TODO: https://golang.org/cl/250039: set Content-Length:0 for empty PATCH requests as with POST, PATCH +

+ +

+ TODO: https://golang.org/cl/249440: match http scheme when selecting http_proxy +

+
net/http/httputil
+
+

+ TODO: https://golang.org/cl/260637: flush ReverseProxy immediately if Content-Length is -1 +

+
+
+ +
net/smtp
+
+

+ TODO: https://golang.org/cl/247257: adds support for the SMTPUTF8 extension +

+
+
+ +
os
+
+

+ TODO: https://golang.org/cl/242998: export errFinished as ErrProcessDone +

+
+
+ +
os/signal
+
+

+ TODO: https://golang.org/cl/219640: add NotifyContext to cancel context using system signals +

+
+
+ +
path
+
+

+ TODO: https://golang.org/cl/264397: validate patterns in Match, Glob +

+
+
+ +
path/filepath
+
+

+ TODO: https://golang.org/cl/264397: validate patterns in Match, Glob +

+
+
+ +
reflect
+
+

+ TODO: https://golang.org/cl/248341: support multiple keys in struct tags +

+
+
+ +
runtime
+
+

+ TODO: https://golang.org/cl/37222: make stack traces of endless recursion print only top and bottom 50 +

+ +

+ TODO: https://golang.org/cl/242258: add 24 byte allocation size class +

+ +

+ TODO: https://golang.org/cl/254659: implement GODEBUG=inittrace=1 support +

+
+
+
runtime/debug

@@ -496,18 +641,6 @@ Do not send CLs removing the interior tags from such phrases.

-
syscall
-
-

- SysProcAttr on Windows has a new NoInheritHandles field that disables inheriting handles when creating a new process. -

- -

- DLLError on Windows now has an Unwrap function for unwrapping its underlying error. -

-
-
-
strconv

@@ -520,3 +653,60 @@ Do not send CLs removing the interior tags from such phrases.

+ +
syscall
+
+

+ SysProcAttr on Windows has a new NoInheritHandles field that disables inheriting handles when creating a new process. +

+ +

+ DLLError on Windows now has an Unwrap function for unwrapping its underlying error. +

+ +

+ TODO: https://golang.org/cl/210639: support POSIX semantics for Linux syscalls +

+
+
+ +
text/template
+
+

+ TODO: https://golang.org/cl/254257: allow newlines inside action delimiters +

+
+
+ +
text/template/parse
+
+

+ A new CommentNode + was added to the parse tree. The Mode + field in the parse.Tree enables access to it. +

+
+
+ +
time/tzdata
+
+

+ The slim timezone data format is now used for the timezone database in + $GOROOT/lib/time/zoneinfo.zip and the embedded copy in this + package. This reduces the size of the timezone database by about 350 KB. +

+
+
+ +
unicode
+
+

+ The unicode package and associated + support throughout the system has been upgraded from Unicode 12.0.0 to + Unicode 13.0.0, + which adds 5,930 new characters, including four new scripts, and 55 new emoji. + Unicode 13.0.0 also designates plane 3 (U+30000-U+3FFFF) as the tertiary + ideographic plane. +

+
+
diff --git a/src/cmd/compile/internal/ssa/expand_calls.go b/src/cmd/compile/internal/ssa/expand_calls.go index 180afab33b..f266e49327 100644 --- a/src/cmd/compile/internal/ssa/expand_calls.go +++ b/src/cmd/compile/internal/ssa/expand_calls.go @@ -250,6 +250,9 @@ func expandCalls(f *Func) { if leafType != selector.Type && !selector.Type.IsEmptyInterface() { // empty interface for #42727 f.Fatalf("Unexpected Load as selector, leaf=%s, selector=%s\n", leaf.LongString(), selector.LongString()) } + if selector.Type.IsEmptyInterface() { + selector.Type = typ.BytePtr + } leaf.copyOf(selector) for _, s := range namedSelects[selector] { locs = append(locs, f.Names[s.locIndex]) diff --git a/src/cmd/internal/objabi/reloctype.go b/src/cmd/internal/objabi/reloctype.go index 938954e07a..649f690194 100644 --- a/src/cmd/internal/objabi/reloctype.go +++ b/src/cmd/internal/objabi/reloctype.go @@ -156,6 +156,9 @@ const ( // R_ARM64_LDST8 sets a LD/ST immediate value to bits [11:0] of a local address. R_ARM64_LDST8 + // R_ARM64_LDST16 sets a LD/ST immediate value to bits [11:1] of a local address. + R_ARM64_LDST16 + // R_ARM64_LDST32 sets a LD/ST immediate value to bits [11:2] of a local address. R_ARM64_LDST32 diff --git a/src/cmd/internal/objabi/reloctype_string.go b/src/cmd/internal/objabi/reloctype_string.go index 693d9631f5..658a44f8b8 100644 --- a/src/cmd/internal/objabi/reloctype_string.go +++ b/src/cmd/internal/objabi/reloctype_string.go @@ -46,32 +46,33 @@ func _() { _ = x[R_ARM64_GOT-36] _ = x[R_ARM64_PCREL-37] _ = x[R_ARM64_LDST8-38] - _ = x[R_ARM64_LDST32-39] - _ = x[R_ARM64_LDST64-40] - _ = x[R_ARM64_LDST128-41] - _ = x[R_POWER_TLS_LE-42] - _ = x[R_POWER_TLS_IE-43] - _ = x[R_POWER_TLS-44] - _ = x[R_ADDRPOWER_DS-45] - _ = x[R_ADDRPOWER_GOT-46] - _ = x[R_ADDRPOWER_PCREL-47] - _ = x[R_ADDRPOWER_TOCREL-48] - _ = x[R_ADDRPOWER_TOCREL_DS-49] - _ = x[R_RISCV_PCREL_ITYPE-50] - _ = x[R_RISCV_PCREL_STYPE-51] - _ = x[R_RISCV_TLS_IE_ITYPE-52] - _ = x[R_RISCV_TLS_IE_STYPE-53] - _ = x[R_PCRELDBL-54] - _ = x[R_ADDRMIPSU-55] - _ = x[R_ADDRMIPSTLS-56] - _ = x[R_ADDRCUOFF-57] - _ = x[R_WASMIMPORT-58] - _ = x[R_XCOFFREF-59] + _ = x[R_ARM64_LDST16-39] + _ = x[R_ARM64_LDST32-40] + _ = x[R_ARM64_LDST64-41] + _ = x[R_ARM64_LDST128-42] + _ = x[R_POWER_TLS_LE-43] + _ = x[R_POWER_TLS_IE-44] + _ = x[R_POWER_TLS-45] + _ = x[R_ADDRPOWER_DS-46] + _ = x[R_ADDRPOWER_GOT-47] + _ = x[R_ADDRPOWER_PCREL-48] + _ = x[R_ADDRPOWER_TOCREL-49] + _ = x[R_ADDRPOWER_TOCREL_DS-50] + _ = x[R_RISCV_PCREL_ITYPE-51] + _ = x[R_RISCV_PCREL_STYPE-52] + _ = x[R_RISCV_TLS_IE_ITYPE-53] + _ = x[R_RISCV_TLS_IE_STYPE-54] + _ = x[R_PCRELDBL-55] + _ = x[R_ADDRMIPSU-56] + _ = x[R_ADDRMIPSTLS-57] + _ = x[R_ADDRCUOFF-58] + _ = x[R_WASMIMPORT-59] + _ = x[R_XCOFFREF-60] } -const _RelocType_name = "R_ADDRR_ADDRPOWERR_ADDRARM64R_ADDRMIPSR_ADDROFFR_WEAKADDROFFR_SIZER_CALLR_CALLARMR_CALLARM64R_CALLINDR_CALLPOWERR_CALLMIPSR_CALLRISCVR_CONSTR_PCRELR_TLS_LER_TLS_IER_GOTOFFR_PLT0R_PLT1R_PLT2R_USEFIELDR_USETYPER_USEIFACER_USEIFACEMETHODR_METHODOFFR_POWER_TOCR_GOTPCRELR_JMPMIPSR_DWARFSECREFR_DWARFFILEREFR_ARM64_TLS_LER_ARM64_TLS_IER_ARM64_GOTPCRELR_ARM64_GOTR_ARM64_PCRELR_ARM64_LDST8R_ARM64_LDST32R_ARM64_LDST64R_ARM64_LDST128R_POWER_TLS_LER_POWER_TLS_IER_POWER_TLSR_ADDRPOWER_DSR_ADDRPOWER_GOTR_ADDRPOWER_PCRELR_ADDRPOWER_TOCRELR_ADDRPOWER_TOCREL_DSR_RISCV_PCREL_ITYPER_RISCV_PCREL_STYPER_RISCV_TLS_IE_ITYPER_RISCV_TLS_IE_STYPER_PCRELDBLR_ADDRMIPSUR_ADDRMIPSTLSR_ADDRCUOFFR_WASMIMPORTR_XCOFFREF" +const _RelocType_name = "R_ADDRR_ADDRPOWERR_ADDRARM64R_ADDRMIPSR_ADDROFFR_WEAKADDROFFR_SIZER_CALLR_CALLARMR_CALLARM64R_CALLINDR_CALLPOWERR_CALLMIPSR_CALLRISCVR_CONSTR_PCRELR_TLS_LER_TLS_IER_GOTOFFR_PLT0R_PLT1R_PLT2R_USEFIELDR_USETYPER_USEIFACER_USEIFACEMETHODR_METHODOFFR_POWER_TOCR_GOTPCRELR_JMPMIPSR_DWARFSECREFR_DWARFFILEREFR_ARM64_TLS_LER_ARM64_TLS_IER_ARM64_GOTPCRELR_ARM64_GOTR_ARM64_PCRELR_ARM64_LDST8R_ARM64_LDST16R_ARM64_LDST32R_ARM64_LDST64R_ARM64_LDST128R_POWER_TLS_LER_POWER_TLS_IER_POWER_TLSR_ADDRPOWER_DSR_ADDRPOWER_GOTR_ADDRPOWER_PCRELR_ADDRPOWER_TOCRELR_ADDRPOWER_TOCREL_DSR_RISCV_PCREL_ITYPER_RISCV_PCREL_STYPER_RISCV_TLS_IE_ITYPER_RISCV_TLS_IE_STYPER_PCRELDBLR_ADDRMIPSUR_ADDRMIPSTLSR_ADDRCUOFFR_WASMIMPORTR_XCOFFREF" -var _RelocType_index = [...]uint16{0, 6, 17, 28, 38, 47, 60, 66, 72, 81, 92, 101, 112, 122, 133, 140, 147, 155, 163, 171, 177, 183, 189, 199, 208, 218, 234, 245, 256, 266, 275, 288, 302, 316, 330, 346, 357, 370, 383, 397, 411, 426, 440, 454, 465, 479, 494, 511, 529, 550, 569, 588, 608, 628, 638, 649, 662, 673, 685, 695} +var _RelocType_index = [...]uint16{0, 6, 17, 28, 38, 47, 60, 66, 72, 81, 92, 101, 112, 122, 133, 140, 147, 155, 163, 171, 177, 183, 189, 199, 208, 218, 234, 245, 256, 266, 275, 288, 302, 316, 330, 346, 357, 370, 383, 397, 411, 425, 440, 454, 468, 479, 493, 508, 525, 543, 564, 583, 602, 622, 642, 652, 663, 676, 687, 699, 709} func (i RelocType) String() string { i -= 1 diff --git a/src/cmd/internal/objabi/util.go b/src/cmd/internal/objabi/util.go index 9479ab2cd9..a73ab479a1 100644 --- a/src/cmd/internal/objabi/util.go +++ b/src/cmd/internal/objabi/util.go @@ -40,7 +40,12 @@ const ( ) func goarm() int { - switch v := envOr("GOARM", defaultGOARM); v { + def := defaultGOARM + if GOOS == "android" && GOARCH == "arm" { + // Android arm devices always support GOARM=7. + def = "7" + } + switch v := envOr("GOARM", def); v { case "5": return 5 case "6": diff --git a/src/cmd/link/internal/arm64/asm.go b/src/cmd/link/internal/arm64/asm.go index cb16180657..a7af855646 100644 --- a/src/cmd/link/internal/arm64/asm.go +++ b/src/cmd/link/internal/arm64/asm.go @@ -177,6 +177,14 @@ func adddynrel(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s loade su.SetRelocType(rIdx, objabi.R_ARM64_LDST8) return true + case objabi.ElfRelocOffset + objabi.RelocType(elf.R_AARCH64_LDST16_ABS_LO12_NC): + if targType == sym.SDYNIMPORT { + ldr.Errorf(s, "unexpected relocation for dynamic symbol %s", ldr.SymName(targ)) + } + su := ldr.MakeSymbolUpdater(s) + su.SetRelocType(rIdx, objabi.R_ARM64_LDST16) + return true + case objabi.ElfRelocOffset + objabi.RelocType(elf.R_AARCH64_LDST32_ABS_LO12_NC): if targType == sym.SDYNIMPORT { ldr.Errorf(s, "unexpected relocation for dynamic symbol %s", ldr.SymName(targ)) @@ -769,6 +777,14 @@ func archreloc(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, r loade o0 := uint32(t&0xfff) << 10 return val | int64(o0), noExtReloc, true + case objabi.R_ARM64_LDST16: + t := ldr.SymAddr(rs) + r.Add() - ((ldr.SymValue(s) + int64(r.Off())) &^ 0xfff) + if t&1 != 0 { + ldr.Errorf(s, "invalid address: %x for relocation type: R_AARCH64_LDST16_ABS_LO12_NC", t) + } + o0 := (uint32(t&0xfff) >> 1) << 10 + return val | int64(o0), noExtReloc, true + case objabi.R_ARM64_LDST32: t := ldr.SymAddr(rs) + r.Add() - ((ldr.SymValue(s) + int64(r.Off())) &^ 0xfff) if t&3 != 0 { diff --git a/src/cmd/link/internal/loadelf/ldelf.go b/src/cmd/link/internal/loadelf/ldelf.go index 5260c6bdcb..db543a5e50 100644 --- a/src/cmd/link/internal/loadelf/ldelf.go +++ b/src/cmd/link/internal/loadelf/ldelf.go @@ -1019,6 +1019,7 @@ func relSize(arch *sys.Arch, pn string, elftype uint32) (uint8, error) { ARM64 | uint32(elf.R_AARCH64_ADR_PREL_PG_HI21)<<16, ARM64 | uint32(elf.R_AARCH64_ADD_ABS_LO12_NC)<<16, ARM64 | uint32(elf.R_AARCH64_LDST8_ABS_LO12_NC)<<16, + ARM64 | uint32(elf.R_AARCH64_LDST16_ABS_LO12_NC)<<16, ARM64 | uint32(elf.R_AARCH64_LDST32_ABS_LO12_NC)<<16, ARM64 | uint32(elf.R_AARCH64_LDST64_ABS_LO12_NC)<<16, ARM64 | uint32(elf.R_AARCH64_LDST128_ABS_LO12_NC)<<16, diff --git a/src/go/constant/value.go b/src/go/constant/value.go index 4a89ef3b94..223c363d9b 100644 --- a/src/go/constant/value.go +++ b/src/go/constant/value.go @@ -371,16 +371,13 @@ func MakeUint64(x uint64) Value { } // MakeFloat64 returns the Float value for x. +// If x is -0.0, the result is 0.0. // If x is not finite, the result is an Unknown. func MakeFloat64(x float64) Value { if math.IsInf(x, 0) || math.IsNaN(x) { return unknownVal{} } - // convert -0 to 0 - if x == 0 { - return int64Val(0) - } - return ratVal{newRat().SetFloat64(x)} + return ratVal{newRat().SetFloat64(x + 0)} // convert -0 to 0 } // MakeFromLiteral returns the corresponding integer, floating-point, @@ -595,11 +592,11 @@ func Make(x interface{}) Value { case int64: return int64Val(x) case *big.Int: - return intVal{x} + return makeInt(x) case *big.Rat: - return ratVal{x} + return makeRat(x) case *big.Float: - return floatVal{x} + return makeFloat(x) default: return unknownVal{} } diff --git a/src/go/constant/value_test.go b/src/go/constant/value_test.go index 1ad6784f9a..91ad0b0c2b 100644 --- a/src/go/constant/value_test.go +++ b/src/go/constant/value_test.go @@ -7,6 +7,7 @@ package constant import ( "fmt" "go/token" + "math" "math/big" "strings" "testing" @@ -620,18 +621,68 @@ func TestUnknown(t *testing.T) { } } -func TestMake(t *testing.T) { - for _, want := range []interface{}{ - false, - "hello", - int64(1), - big.NewInt(10), - big.NewFloat(2.0), - big.NewRat(1, 3), +func TestMakeFloat64(t *testing.T) { + var zero float64 + for _, arg := range []float64{ + -math.MaxFloat32, + -10, + -0.5, + -zero, + zero, + 1, + 10, + 123456789.87654321e-23, + 1e10, + math.MaxFloat64, } { - got := Val(Make(want)) - if got != want { - t.Errorf("got %v; want %v", got, want) + val := MakeFloat64(arg) + if val.Kind() != Float { + t.Errorf("%v: got kind = %d; want %d", arg, val.Kind(), Float) + } + + // -0.0 is mapped to 0.0 + got, exact := Float64Val(val) + if !exact || math.Float64bits(got) != math.Float64bits(arg+0) { + t.Errorf("%v: got %v (exact = %v)", arg, got, exact) + } + } + + // infinity + for sign := range []int{-1, 1} { + arg := math.Inf(sign) + val := MakeFloat64(arg) + if val.Kind() != Unknown { + t.Errorf("%v: got kind = %d; want %d", arg, val.Kind(), Unknown) + } + } +} + +type makeTestCase struct { + kind Kind + arg, want interface{} +} + +func dup(k Kind, x interface{}) makeTestCase { return makeTestCase{k, x, x} } + +func TestMake(t *testing.T) { + for _, test := range []makeTestCase{ + {Bool, false, false}, + {String, "hello", "hello"}, + + {Int, int64(1), int64(1)}, + {Int, big.NewInt(10), int64(10)}, + {Int, new(big.Int).Lsh(big.NewInt(1), 62), int64(1 << 62)}, + dup(Int, new(big.Int).Lsh(big.NewInt(1), 63)), + + {Float, big.NewFloat(0), floatVal0.val}, + dup(Float, big.NewFloat(2.0)), + dup(Float, big.NewRat(1, 3)), + } { + val := Make(test.arg) + got := Val(val) + if val.Kind() != test.kind || got != test.want { + t.Errorf("got %v (%T, kind = %d); want %v (%T, kind = %d)", + got, got, val.Kind(), test.want, test.want, test.kind) } } } diff --git a/src/regexp/syntax/doc.go b/src/regexp/syntax/doc.go index efc0b43571..b3f9136b5f 100644 --- a/src/regexp/syntax/doc.go +++ b/src/regexp/syntax/doc.go @@ -66,7 +66,7 @@ Grouping: Empty strings: ^ at beginning of text or line (flag m=true) - $ at end of text (like \z not Perl's \Z) or line (flag m=true) + $ at end of text (like \z not \Z) or line (flag m=true) \A at beginning of text \b at ASCII word boundary (\w on one side and \W, \A, or \z on the other) \B not at ASCII word boundary @@ -127,5 +127,6 @@ ASCII character classes: [[:word:]] word characters (== [0-9A-Za-z_]) [[:xdigit:]] hex digit (== [0-9A-Fa-f]) +Unicode character classes are those in unicode.Categories and unicode.Scripts. */ package syntax diff --git a/src/runtime/chan.go b/src/runtime/chan.go index 254816e369..ba56e2cc40 100644 --- a/src/runtime/chan.go +++ b/src/runtime/chan.go @@ -215,7 +215,7 @@ func chansend(c *hchan, ep unsafe.Pointer, block bool, callerpc uintptr) bool { // Space is available in the channel buffer. Enqueue the element to send. qp := chanbuf(c, c.sendx) if raceenabled { - racereleaseacquire(qp) + racenotify(c, c.sendx, nil) } typedmemmove(c.elemtype, qp, ep) c.sendx++ @@ -297,9 +297,8 @@ func send(c *hchan, sg *sudog, ep unsafe.Pointer, unlockf func(), skip int) { // Pretend we go through the buffer, even though // we copy directly. Note that we need to increment // the head/tail locations only when raceenabled. - qp := chanbuf(c, c.recvx) - racereleaseacquire(qp) - racereleaseacquireg(sg.g, qp) + racenotify(c, c.recvx, nil) + racenotify(c, c.recvx, sg) c.recvx++ if c.recvx == c.dataqsiz { c.recvx = 0 @@ -532,7 +531,7 @@ func chanrecv(c *hchan, ep unsafe.Pointer, block bool) (selected, received bool) // Receive directly from queue qp := chanbuf(c, c.recvx) if raceenabled { - racereleaseacquire(qp) + racenotify(c, c.recvx, nil) } if ep != nil { typedmemmove(c.elemtype, ep, qp) @@ -621,8 +620,8 @@ func recv(c *hchan, sg *sudog, ep unsafe.Pointer, unlockf func(), skip int) { // queue is full, those are both the same slot. qp := chanbuf(c, c.recvx) if raceenabled { - racereleaseacquire(qp) - racereleaseacquireg(sg.g, qp) + racenotify(c, c.recvx, nil) + racenotify(c, c.recvx, sg) } // copy data from queue to receiver if ep != nil { @@ -833,3 +832,38 @@ func racesync(c *hchan, sg *sudog) { racereleaseg(sg.g, chanbuf(c, 0)) raceacquire(chanbuf(c, 0)) } + +// Notify the race detector of a send or receive involving buffer entry idx +// and a channel c or its communicating partner sg. +// This function handles the special case of c.elemsize==0. +func racenotify(c *hchan, idx uint, sg *sudog) { + // We could have passed the unsafe.Pointer corresponding to entry idx + // instead of idx itself. However, in a future version of this function, + // we can use idx to better handle the case of elemsize==0. + // A future improvement to the detector is to call TSan with c and idx: + // this way, Go will continue to not allocating buffer entries for channels + // of elemsize==0, yet the race detector can be made to handle multiple + // sync objects underneath the hood (one sync object per idx) + qp := chanbuf(c, idx) + // When elemsize==0, we don't allocate a full buffer for the channel. + // Instead of individual buffer entries, the race detector uses the + // c.buf as the only buffer entry. This simplification prevents us from + // following the memory model's happens-before rules (rules that are + // implemented in racereleaseacquire). Instead, we accumulate happens-before + // information in the synchronization object associated with c.buf. + if c.elemsize == 0 { + if sg == nil { + raceacquire(qp) + racerelease(qp) + } else { + raceacquireg(sg.g, qp) + racereleaseg(sg.g, qp) + } + } else { + if sg == nil { + racereleaseacquire(qp) + } else { + racereleaseacquireg(sg.g, qp) + } + } +} diff --git a/src/runtime/crash_cgo_test.go b/src/runtime/crash_cgo_test.go index 0680d07a32..140c170ddc 100644 --- a/src/runtime/crash_cgo_test.go +++ b/src/runtime/crash_cgo_test.go @@ -254,6 +254,24 @@ func TestCgoCrashTraceback(t *testing.T) { } } +func TestCgoCrashTracebackGo(t *testing.T) { + t.Parallel() + switch platform := runtime.GOOS + "/" + runtime.GOARCH; platform { + case "darwin/amd64": + case "linux/amd64": + case "linux/ppc64le": + default: + t.Skipf("not yet supported on %s", platform) + } + got := runTestProg(t, "testprogcgo", "CrashTracebackGo") + for i := 1; i <= 3; i++ { + want := fmt.Sprintf("main.h%d", i) + if !strings.Contains(got, want) { + t.Errorf("missing %s", want) + } + } +} + func TestCgoTracebackContext(t *testing.T) { t.Parallel() got := runTestProg(t, "testprogcgo", "TracebackContext") diff --git a/src/runtime/race/testdata/chan_test.go b/src/runtime/race/testdata/chan_test.go index 3e57b8221c..e39ad4f99c 100644 --- a/src/runtime/race/testdata/chan_test.go +++ b/src/runtime/race/testdata/chan_test.go @@ -763,3 +763,25 @@ func TestNoRaceCloseHappensBeforeRead(t *testing.T) { <-read } } + +// Test that we call the proper race detector function when c.elemsize==0. +// See https://github.com/golang/go/issues/42598 +func TestNoRaceElemetSize0(t *testing.T) { + var x, y int + var c = make(chan struct{}, 2) + c <- struct{}{} + c <- struct{}{} + go func() { + x += 1 + <-c + }() + go func() { + y += 1 + <-c + }() + time.Sleep(10 * time.Millisecond) + c <- struct{}{} + c <- struct{}{} + x += 1 + y += 1 +} diff --git a/src/runtime/select.go b/src/runtime/select.go index f04b130b15..e72761bfa9 100644 --- a/src/runtime/select.go +++ b/src/runtime/select.go @@ -415,7 +415,7 @@ bufrecv: if cas.elem != nil { raceWriteObjectPC(c.elemtype, cas.elem, casePC(casi), chanrecvpc) } - racereleaseacquire(chanbuf(c, c.recvx)) + racenotify(c, c.recvx, nil) } if msanenabled && cas.elem != nil { msanwrite(cas.elem, c.elemtype.size) @@ -437,7 +437,7 @@ bufrecv: bufsend: // can send to buffer if raceenabled { - racereleaseacquire(chanbuf(c, c.sendx)) + racenotify(c, c.sendx, nil) raceReadObjectPC(c.elemtype, cas.elem, casePC(casi), chansendpc) } if msanenabled { diff --git a/src/runtime/stack_test.go b/src/runtime/stack_test.go index adfc65384a..43fc5cac55 100644 --- a/src/runtime/stack_test.go +++ b/src/runtime/stack_test.go @@ -17,6 +17,7 @@ import ( "sync/atomic" "testing" "time" + _ "unsafe" // for go:linkname ) // TestStackMem measures per-thread stack segment cache behavior. @@ -851,3 +852,43 @@ func deferHeapAndStack(n int) (r int) { // Pass a value to escapeMe to force it to escape. var escapeMe = func(x interface{}) {} + +// Test that when F -> G is inlined and F is excluded from stack +// traces, G still appears. +func TestTracebackInlineExcluded(t *testing.T) { + defer func() { + recover() + buf := make([]byte, 4<<10) + stk := string(buf[:Stack(buf, false)]) + + t.Log(stk) + + if not := "tracebackExcluded"; strings.Contains(stk, not) { + t.Errorf("found but did not expect %q", not) + } + if want := "tracebackNotExcluded"; !strings.Contains(stk, want) { + t.Errorf("expected %q in stack", want) + } + }() + tracebackExcluded() +} + +// tracebackExcluded should be excluded from tracebacks. There are +// various ways this could come up. Linking it to a "runtime." name is +// rather synthetic, but it's easy and reliable. See issue #42754 for +// one way this happened in real code. +// +//go:linkname tracebackExcluded runtime.tracebackExcluded +//go:noinline +func tracebackExcluded() { + // Call an inlined function that should not itself be excluded + // from tracebacks. + tracebackNotExcluded() +} + +// tracebackNotExcluded should be inlined into tracebackExcluded, but +// should not itself be excluded from the traceback. +func tracebackNotExcluded() { + var x *int + *x = 0 +} diff --git a/src/runtime/sys_windows_386.s b/src/runtime/sys_windows_386.s index 2e5e82879c..ef8a3dd3c2 100644 --- a/src/runtime/sys_windows_386.s +++ b/src/runtime/sys_windows_386.s @@ -415,12 +415,15 @@ TEXT runtime·usleep2(SB),NOSPLIT,$20 // Runs on OS stack. duration (in 100ns units) is in BX. TEXT runtime·usleep2HighRes(SB),NOSPLIT,$36 + get_tls(CX) + CMPL CX, $0 + JE gisnotset + // Want negative 100ns units. NEGL BX MOVL $-1, hi-4(SP) MOVL BX, lo-8(SP) - get_tls(CX) MOVL g(CX), CX MOVL g_m(CX), CX MOVL (m_mOS+mOS_highResTimer)(CX), CX @@ -449,6 +452,12 @@ TEXT runtime·usleep2HighRes(SB),NOSPLIT,$36 RET +gisnotset: + // TLS is not configured. Call usleep2 instead. + MOVL $runtime·usleep2(SB), AX + CALL AX + RET + // Runs on OS stack. TEXT runtime·switchtothread(SB),NOSPLIT,$0 MOVL SP, BP diff --git a/src/runtime/sys_windows_amd64.s b/src/runtime/sys_windows_amd64.s index e9ec99a51d..d1690cad58 100644 --- a/src/runtime/sys_windows_amd64.s +++ b/src/runtime/sys_windows_amd64.s @@ -454,11 +454,14 @@ TEXT runtime·usleep2(SB),NOSPLIT|NOFRAME,$48 // Runs on OS stack. duration (in 100ns units) is in BX. TEXT runtime·usleep2HighRes(SB),NOSPLIT|NOFRAME,$72 + get_tls(CX) + CMPQ CX, $0 + JE gisnotset + MOVQ SP, AX ANDQ $~15, SP // alignment as per Windows requirement MOVQ AX, 64(SP) - get_tls(CX) MOVQ g(CX), CX MOVQ g_m(CX), CX MOVQ (m_mOS+mOS_highResTimer)(CX), CX // hTimer @@ -484,6 +487,12 @@ TEXT runtime·usleep2HighRes(SB),NOSPLIT|NOFRAME,$72 MOVQ 64(SP), SP RET +gisnotset: + // TLS is not configured. Call usleep2 instead. + MOVQ $runtime·usleep2(SB), AX + CALL AX + RET + // Runs on OS stack. TEXT runtime·switchtothread(SB),NOSPLIT|NOFRAME,$0 MOVQ SP, AX diff --git a/src/runtime/testdata/testprogcgo/traceback.go b/src/runtime/testdata/testprogcgo/traceback.go index 2a023f66ca..e2d7599131 100644 --- a/src/runtime/testdata/testprogcgo/traceback.go +++ b/src/runtime/testdata/testprogcgo/traceback.go @@ -11,58 +11,11 @@ package main /* #cgo CFLAGS: -g -O0 -#include - -char *p; - -static int f3(void) { - *p = 0; - return 0; -} - -static int f2(void) { - return f3(); -} - -static int f1(void) { - return f2(); -} - -struct cgoTracebackArg { - uintptr_t context; - uintptr_t sigContext; - uintptr_t* buf; - uintptr_t max; -}; - -struct cgoSymbolizerArg { - uintptr_t pc; - const char* file; - uintptr_t lineno; - const char* func; - uintptr_t entry; - uintptr_t more; - uintptr_t data; -}; - -void cgoTraceback(void* parg) { - struct cgoTracebackArg* arg = (struct cgoTracebackArg*)(parg); - arg->buf[0] = 1; - arg->buf[1] = 2; - arg->buf[2] = 3; - arg->buf[3] = 0; -} - -void cgoSymbolizer(void* parg) { - struct cgoSymbolizerArg* arg = (struct cgoSymbolizerArg*)(parg); - if (arg->pc != arg->data + 1) { - arg->file = "unexpected data"; - } else { - arg->file = "cgo symbolizer"; - } - arg->lineno = arg->data + 1; - arg->data++; -} +// Defined in traceback_c.c. +extern int crashInGo; +int tracebackF1(void); +void cgoTraceback(void* parg); +void cgoSymbolizer(void* parg); */ import "C" @@ -73,9 +26,29 @@ import ( func init() { register("CrashTraceback", CrashTraceback) + register("CrashTracebackGo", CrashTracebackGo) } func CrashTraceback() { runtime.SetCgoTraceback(0, unsafe.Pointer(C.cgoTraceback), nil, unsafe.Pointer(C.cgoSymbolizer)) - C.f1() + C.tracebackF1() +} + +func CrashTracebackGo() { + C.crashInGo = 1 + CrashTraceback() +} + +//export h1 +func h1() { + h2() +} + +func h2() { + h3() +} + +func h3() { + var x *int + *x = 0 } diff --git a/src/runtime/testdata/testprogcgo/traceback_c.c b/src/runtime/testdata/testprogcgo/traceback_c.c new file mode 100644 index 0000000000..56eda8fa8c --- /dev/null +++ b/src/runtime/testdata/testprogcgo/traceback_c.c @@ -0,0 +1,65 @@ +// 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. + +// The C definitions for traceback.go. That file uses //export so +// it can't put function definitions in the "C" import comment. + +#include + +char *p; + +int crashInGo; +extern void h1(void); + +int tracebackF3(void) { + if (crashInGo) + h1(); + else + *p = 0; + return 0; +} + +int tracebackF2(void) { + return tracebackF3(); +} + +int tracebackF1(void) { + return tracebackF2(); +} + +struct cgoTracebackArg { + uintptr_t context; + uintptr_t sigContext; + uintptr_t* buf; + uintptr_t max; +}; + +struct cgoSymbolizerArg { + uintptr_t pc; + const char* file; + uintptr_t lineno; + const char* func; + uintptr_t entry; + uintptr_t more; + uintptr_t data; +}; + +void cgoTraceback(void* parg) { + struct cgoTracebackArg* arg = (struct cgoTracebackArg*)(parg); + arg->buf[0] = 1; + arg->buf[1] = 2; + arg->buf[2] = 3; + arg->buf[3] = 0; +} + +void cgoSymbolizer(void* parg) { + struct cgoSymbolizerArg* arg = (struct cgoSymbolizerArg*)(parg); + if (arg->pc != arg->data + 1) { + arg->file = "unexpected data"; + } else { + arg->file = "cgo symbolizer"; + } + arg->lineno = arg->data + 1; + arg->data++; +} diff --git a/src/runtime/traceback.go b/src/runtime/traceback.go index f3df152535..0825e9e707 100644 --- a/src/runtime/traceback.go +++ b/src/runtime/traceback.go @@ -396,13 +396,21 @@ func gentraceback(pc0, sp0, lr0 uintptr, gp *g, skip int, pcbuf *uintptr, max in // If there is inlining info, print the inner frames. if inldata := funcdata(f, _FUNCDATA_InlTree); inldata != nil { inltree := (*[1 << 20]inlinedCall)(inldata) + var inlFunc _func + inlFuncInfo := funcInfo{&inlFunc, f.datap} for { ix := pcdatavalue(f, _PCDATA_InlTreeIndex, tracepc, nil) if ix < 0 { break } - if (flags&_TraceRuntimeFrames) != 0 || showframe(f, gp, nprint == 0, inltree[ix].funcID, lastFuncID) { - name := funcnameFromNameoff(f, inltree[ix].func_) + + // Create a fake _func for the + // inlined function. + inlFunc.nameoff = inltree[ix].func_ + inlFunc.funcID = inltree[ix].funcID + + if (flags&_TraceRuntimeFrames) != 0 || showframe(inlFuncInfo, gp, nprint == 0, inlFuncInfo.funcID, lastFuncID) { + name := funcname(inlFuncInfo) file, line := funcline(f, tracepc) print(name, "(...)\n") print("\t", file, ":", line, "\n") @@ -811,6 +819,9 @@ func showframe(f funcInfo, gp *g, firstFrame bool, funcID, childID funcID) bool // showfuncinfo reports whether a function with the given characteristics should // be printed during a traceback. func showfuncinfo(f funcInfo, firstFrame bool, funcID, childID funcID) bool { + // Note that f may be a synthesized funcInfo for an inlined + // function, in which case only nameoff and funcID are set. + level, _, _ := gotraceback() if level > 1 { // Show all frames. diff --git a/test/fixedbugs/issue42784.go b/test/fixedbugs/issue42784.go new file mode 100644 index 0000000000..e2b06e9307 --- /dev/null +++ b/test/fixedbugs/issue42784.go @@ -0,0 +1,26 @@ +// compile + +// 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. + +// Ensure that late expansion correctly set OpLoad argument type interface{} + +package p + +type iface interface { + m() +} + +type it interface{} + +type makeIface func() iface + +func f() { + var im makeIface + e := im().(it) + g(e) +} + +//go:noinline +func g(i it) {}