Compare commits

...

59 Commits

Author SHA1 Message Date
Alexander Rakoczy
de690c2ff8 [release-branch.go1.17] go1.17.5
Change-Id: Ief6fb9e836c1d40ece56868d65ebf65f74e65665
Reviewed-on: https://go-review.googlesource.com/c/go/+/370555
Trust: Alex Rakoczy <alex@golang.org>
Run-TryBot: Alex Rakoczy <alex@golang.org>
Reviewed-by: Filippo Valsorda <filippo@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
2021-12-09 13:44:55 +00:00
Filippo Valsorda
48d948963c [release-branch.go1.17] net/http: update bundled golang.org/x/net/http2
Pull in security fix

    84cba54 http2: cap the size of the server's canonical header cache

Updates #50058
Fixes CVE-2021-44716

Change-Id: Ia89e3d22a173c6cb83f03608d5186fcd08f2956c
Reviewed-on: https://go-review.googlesource.com/c/go/+/370574
Trust: Filippo Valsorda <filippo@golang.org>
Run-TryBot: Filippo Valsorda <filippo@golang.org>
Reviewed-by: Alex Rakoczy <alex@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
2021-12-09 13:07:36 +00:00
Russ Cox
65633fee16 [release-branch.go1.17] syscall: avoid writing to p when Pipe(p) fails
Generally speaking Go functions make no guarantees
about what has happened to result parameters on error,
and Pipe is no exception: callers should avoid looking at
p if Pipe returns an error.

However, we had a bug in which ForkExec was using the
content of p after a failed Pipe, and others may too.
As a robustness fix, make Pipe avoid writing to p on failure.

Updates #50057

Change-Id: Ie8955025dbd20702fabadc9bbe1d1a5ac0f36305
Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/1291271
Reviewed-by: Ian Lance Taylor <iant@google.com>
Reviewed-on: https://go-review.googlesource.com/c/go/+/370535
Trust: Filippo Valsorda <filippo@golang.org>
Run-TryBot: Filippo Valsorda <filippo@golang.org>
Reviewed-by: Alex Rakoczy <alex@golang.org>
2021-12-09 12:28:48 +00:00
Russ Cox
e46abcb816 [release-branch.go1.17] syscall: fix ForkLock spurious close(0) on pipe failure
Pipe (and therefore forkLockPipe) does not make any guarantees
about the state of p after a failed Pipe(p). Avoid that assumption
and the too-clever goto, so that we don't accidentally Close a real fd
if the failed pipe leaves p[0] or p[1] set >= 0.

Updates #50057
Fixes CVE-2021-44717

Change-Id: Iff8e19a6efbba0c73cc8b13ecfae381c87600bb4
Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/1291270
Reviewed-by: Ian Lance Taylor <iant@google.com>
Reviewed-on: https://go-review.googlesource.com/c/go/+/370534
Trust: Filippo Valsorda <filippo@golang.org>
Run-TryBot: Filippo Valsorda <filippo@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Alex Rakoczy <alex@golang.org>
2021-12-09 12:28:39 +00:00
Heschi Kreinick
61317ef99e [release-branch.go1.17] misc/cgo/testplugin: skip TestIssue25756pie on darwin/arm64 builder
Repeat of CL 321349 for macOS 12. We won't need to do this again -- the
test is passing at tip.

Updates #46239.

Change-Id: Ib279ada443ee03eb8e70fde4bbfba65ce0f6322e
Reviewed-on: https://go-review.googlesource.com/c/go/+/369748
Trust: Heschi Kreinick <heschi@google.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org>
Run-TryBot: Heschi Kreinick <heschi@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
2021-12-06 23:45:46 +00:00
Heschi Kreinick
0f2d0d0694 [release-branch.go1.17] go1.17.4
Change-Id: I11748377b7a35bd38b52e6f81093cc210f6d2857
Reviewed-on: https://go-review.googlesource.com/c/go/+/368695
Trust: Heschi Kreinick <heschi@google.com>
Trust: Michael Knyszek <mknyszek@google.com>
Run-TryBot: Heschi Kreinick <heschi@google.com>
Run-TryBot: Michael Knyszek <mknyszek@google.com>
Reviewed-by: Heschi Kreinick <heschi@google.com>
2021-12-02 20:02:34 +00:00
Cuong Manh Le
759a9211d4 [release-branch.go1.17] cmd/compile: only update source type when processing struct/array
This is backport of CL 3651594, with the test from CL 360057.

CL 360057 fixed missing update source type in storeArgOrLoad. However,
we should only update the type when processing struct/array. If we
update the type right before calling storeArgOrLoad, we may generate a
value with invalid type, e.g, OpStructSelect with non-struct type.

Fixes #49392

Change-Id: Ib7e10f72f818880f550aae5c9f653db463ce29b0
Reviewed-on: https://go-review.googlesource.com/c/go/+/361594
Trust: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: David Chase <drchase@google.com>
Reviewed-on: https://go-review.googlesource.com/c/go/+/361596
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
2021-12-02 17:52:07 +00:00
Michael Anthony Knyszek
01779135c0 [release-branch.go1.17] net/http: update bundled golang.org/x/net/http2
Pull in approved backports to golang.org/x/net/http2:

    85e122b net/http2: Fix handling of expect continue
    1dc0aec http2: don't count aborted streams as active in tests
    e973a42 ipv6: OpenBSD does not appear to support multicast loopback
    9592dd5 http2: avoid busy loop when ResponseHeaderTimeout is set
    94fb2bc http2: avoid spurious RoundTrip error when server closes and resets stream
    e108c19 http2: close conns after use when req.Close is set

By doing:

    $ go get -d golang.org/x/net@internal-branch.go1.17-vendor
    go: upgraded golang.org/x/net v0.0.0-20211101194204-95aca89e93de => v0.0.0-20211201233630-85e122b1a9b3
    $ go mod tidy
    $ go mod vendor
    $ go generate -run=bundle std

Fixes #49561.
Fixes #49624.
Fixes #49662.
Fixes #49905.
Fixes #49909.
Fixes #49911.

Change-Id: Ia8f432bd3ea77d24e63d46c8ed2ac8d275406b52
Reviewed-on: https://go-review.googlesource.com/c/go/+/368574
Trust: Michael Knyszek <mknyszek@google.com>
Run-TryBot: Michael Knyszek <mknyszek@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org>
2021-12-02 04:43:37 +00:00
Robert Griesemer
66007e5cfc [release-branch.go1.17] go/types: break cycles in invalid types
This is a partial port of CL 354329 from types2 to go/types.
It contains an adjustment to type.go to deal with possibly
invalid type bounds.

Fixes #48825.
For #48819.

Change-Id: I9efdcdbfa6432f3cee64d924a4c67ecc6793cf86
Reviewed-on: https://go-review.googlesource.com/c/go/+/354349
Trust: Robert Griesemer <gri@golang.org>
Reviewed-by: Robert Findley <rfindley@google.com>
Reviewed-on: https://go-review.googlesource.com/c/go/+/368456
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
2021-12-01 23:34:46 +00:00
Damien Neil
3c50f27391 [release-branch.go1.17] net/http: do not send Transfer-Encoding: identity in responses
Server handlers may set a "Transfer-Encoding: identity" header on
responses to disable chunking, but this header should not be sent
on the wire.

For #49194.
Fixes #49568.

Change-Id: I46a9e3b8ff9d93edd7d1c34d264fc309fa322ad5
Reviewed-on: https://go-review.googlesource.com/c/go/+/359176
Trust: Damien Neil <dneil@google.com>
Run-TryBot: Damien Neil <dneil@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
(cherry picked from commit b69b2f63d6)
Reviewed-on: https://go-review.googlesource.com/c/go/+/368087
Reviewed-by: Michael Knyszek <mknyszek@google.com>
2021-12-01 22:10:49 +00:00
Damien Neil
ab175939e2 [release-branch.go1.17] net/http: do not cancel request context on response body read
When sending a Request with a non-context deadline, we create a
context with a timeout. This context is canceled when closing the
response body, and also if a read from the response body returns
an error (including io.EOF).

Cancelling the context in Response.Body.Read interferes with the
HTTP/2 client cleaning up after a request is completed, and is
unnecessary: The user should always close the body, the impact
from not canceling the context is minor (the context timer leaks
until it fires).

Fixes #49559.
For #49366.

Change-Id: Ieaed866116916261d9079f71d8fea7a7b303b8fb
Reviewed-on: https://go-review.googlesource.com/c/go/+/361919
Trust: Damien Neil <dneil@google.com>
Run-TryBot: Damien Neil <dneil@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
(cherry picked from commit 76fbd61673)
Reviewed-on: https://go-review.googlesource.com/c/go/+/368085
Reviewed-by: Michael Knyszek <mknyszek@google.com>
2021-12-01 22:10:22 +00:00
Jason A. Donenfeld
f0ee7c6f96 [release-branch.go1.17] runtime: keep //go:cgo_unsafe_args arguments alive to prevent GC
When syscall's DLL.FindProc calls into syscall_getprocaddress with a
byte slice pointer, we need to keep those bytes alive. Otherwise the GC
will collect the allocation, and we wind up calling `GetProcAddress` on
garbage, which showed up as various flakes in the builders. It turns out
that this problem extends to many uses of //go:cgo_unsafe_args
throughout, on all platforms. So this patch fixes the issue by keeping
non-integer pointer arguments alive through their invocation in
//go:cgo_unsafe_args functions.

Fixes #49868.
Updates #49731.

Change-Id: I93e4fbc2e8e210cb3fc53149708758bb33f2f9c7
Reviewed-on: https://go-review.googlesource.com/c/go/+/368355
Trust: Jason A. Donenfeld <Jason@zx2c4.com>
Run-TryBot: Jason A. Donenfeld <Jason@zx2c4.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
2021-12-01 22:09:30 +00:00
zhouguangyuan
b7651e5046 [release-branch.go1.17] time: fix looking for zone offset when date is close to a zone transition
The old implement passed start - 1 or end in func lookup to adjust the offset.But if the time is close to the last zoneTrans, like the issue, testcase and comment, the "start" from lookup will be omega. It can't be adjusted correctly.

Fixes #49407

Change-Id: Ibaf82dc4db6d5dd3279796f003d2b19c38a26341
Reviewed-on: https://go-review.googlesource.com/c/go/+/360616
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Trust: Robert Findley <rfindley@google.com>
(cherry picked from commit 90462dfc3a)
Reviewed-on: https://go-review.googlesource.com/c/go/+/361955
Trust: Dmitri Shuralyov <dmitshur@golang.org>
2021-11-29 19:46:17 +00:00
Dan Scales
4eaf0b7a58 [release-branch.go1.17] cmd/compile: fix case where init info of OAS node is dropped
When an OAS node is converted to an OSELRECV2 node in tcSelect(), the
possible DCL node in the Init field was being dropped, since a
completely new node was being created and the Init field was not set. I
don't expect n.Init() to be set for the ORECV case, but the code now
deals with that too.

Fixed bug in both tcSelect() and transformSelect().

Cherry-picked from https://go-review.googlesource.com/c/go/+/348569

Fixes #49511

Change-Id: Id5b736daa8e90afda88aaa3769dde801db294c0d
Reviewed-on: https://go-review.googlesource.com/c/go/+/363664
Trust: Dan Scales <danscales@google.com>
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
2021-11-24 19:38:31 +00:00
Jason A. Donenfeld
4536558f16 [release-branch.go1.17] runtime: use correct constant when computing nsec remainder
A code comment on amd64 for windows and plan9 contained a snippet for
splitting apart the sec and nsec components of a unix timestamp, with
produced assembly below, which was then cleaned up by hand. When arm64
was ported, that code snippet in the comment went through the compiler
to produce some code that was then pasted and cleaned up. Unfortunately,
the comment had a typo in it, containing 8 zeros instead of 9.

This resulted in the constant used in the assembly being wrong, spotted
by @bufflig's eagle eyes. So, this commit fixes the comment on all three
platforms, and the assembly on windows/arm64.

Updates #48072.
Fixes #49369.

Change-Id: I786fe89147328b0d25544f52c927ddfdb9f6f1cf
Reviewed-on: https://go-review.googlesource.com/c/go/+/361474
Trust: Jason A. Donenfeld <Jason@zx2c4.com>
Run-TryBot: Jason A. Donenfeld <Jason@zx2c4.com>
Reviewed-by: Patrik Nyblom <pnyb@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-on: https://go-review.googlesource.com/c/go/+/361476
2021-11-24 19:34:05 +00:00
Jason A. Donenfeld
e347c89598 [release-branch.go1.17] runtime: on windows, read nanotime with one instruction or issue barrier
On 64-bit, this is more efficient, and on ARM64, this prevents the time
from moving backwards due to the weaker memory model. On ARM32 due to
the weaker memory model, we issue a memory barrier.

Updates #48072.
Updates #49369.

Change-Id: If4695716c3039d8af14e14808af217f5c99fc93a
Reviewed-on: https://go-review.googlesource.com/c/go/+/361057
Trust: Jason A. Donenfeld <Jason@zx2c4.com>
Run-TryBot: Jason A. Donenfeld <Jason@zx2c4.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Austin Clements <austin@google.com>
Reviewed-on: https://go-review.googlesource.com/c/go/+/361475
Reviewed-by: Patrik Nyblom <pnyb@google.com>
2021-11-24 19:33:56 +00:00
Keith Randall
1c05b9b024 [release-branch.go1.17] cmd/compile: fix fuse pass to do CFG surgery correctly
removePred and removeArg do different things. removePred moves the last
predecessor to index k, whereas removeArg slides all the args k or
greater down by 1 index.

Kind of unfortunate different behavior in things named similarly.

Fixes #49129

Change-Id: I9ae409bdac744e713f4c121f948e43db6fdc8542
Reviewed-on: https://go-review.googlesource.com/c/go/+/358117
Trust: Keith Randall <khr@golang.org>
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
(cherry picked from commit 8dbf3e9393)
Reviewed-on: https://go-review.googlesource.com/c/go/+/358118
Reviewed-by: Austin Clements <austin@google.com>
Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com>
2021-11-24 19:33:23 +00:00
Bryan C. Mills
364f15ff9f [release-branch.go1.17] cmd/go: forward the MallocNanoZone variable to script tests
For #49138
Updates #49723
Fixes #49729

Change-Id: Ia93130fdc042a1e2107be95cccd7e7eeaa909a87
Reviewed-on: https://go-review.googlesource.com/c/go/+/366254
Trust: Bryan C. Mills <bcmills@google.com>
Run-TryBot: Bryan C. Mills <bcmills@google.com>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
(cherry picked from commit 189b4a2f42)
Reviewed-on: https://go-review.googlesource.com/c/go/+/366257
TryBot-Result: Go Bot <gobot@golang.org>
2021-11-22 20:49:19 +00:00
Cherry Mui
b954f58e9d [release-branch.go1.17] cmd/link: don't use label symbol for absolute address relocations on ARM64 PE
On ARM64 PE, when external linking, the PE relocation does not
have an explicit addend, and instead has the addend encoded in
the instruction or data. An instruction (e.g. ADRP, ADD) has
limited width for the addend, so when the addend is large we use
a label symbol, which points to the middle of the original target
symbol, and a smaller addend. But for an absolute address
relocation in the data section, we have the full width to encode
the addend and we should not use the label symbol. Also, since we
do not adjust the addend in the data, using the label symbol will
actually make it point to the wrong address. E.g for an R_ADDR
relocation targeting x+0x123456, we should emit 0x123456 in the
data with an IMAGE_REL_ARM64_ADDR64 relocation pointing to x,
whereas the current code emits  0x123456 in the data with an
IMAGE_REL_ARM64_ADDR64 relocation pointing to the label symbol
x+1MB, so it will actually be resolved to x+0x223456. This CL
fixes this.

Fixes #49479

Change-Id: I64e02b56f1d792f8c20ca61b78623ef5c3e34d7e
Reviewed-on: https://go-review.googlesource.com/c/go/+/360895
Trust: Cherry Mui <cherryyz@google.com>
Run-TryBot: Cherry Mui <cherryyz@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Than McIntosh <thanm@google.com>
(cherry picked from commit 988efd5819)
Reviewed-on: https://go-review.googlesource.com/c/go/+/363014
Run-TryBot: Carlos Amedee <carlos@golang.org>
Reviewed-by: Cherry Mui <cherryyz@google.com>
2021-11-10 19:35:55 +00:00
Cuong Manh Le
f1935e2c43 [release-branch.go1.17] cmd/go: fix mod_get_direct
https://github.com/googleapis/google-cloud-go has changed the default
branch from master to main, causing mod_get_direct failed on longtest.

Change-Id: I8fe0356b2ff532d1fdedbcb1e1832d7335babaa0
Reviewed-on: https://go-review.googlesource.com/c/go/+/361965
Trust: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Bryan C. Mills <bcmills@google.com>
(cherry picked from commit b7529c3617)
Reviewed-on: https://go-review.googlesource.com/c/go/+/362535
Trust: Bryan C. Mills <bcmills@google.com>
Run-TryBot: Bryan C. Mills <bcmills@google.com>
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org>
2021-11-09 16:04:46 +00:00
Than McIntosh
f58c78a577 [release-branch.go1.17] go1.17.3
Change-Id: Iaf0b58846a9641525f43f4dc64962c13c0c7e8e3
Reviewed-on: https://go-review.googlesource.com/c/go/+/361200
Trust: Than McIntosh <thanm@google.com>
Run-TryBot: Than McIntosh <thanm@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org>
2021-11-04 13:55:24 +00:00
Jason7602
b212ba6829 [release-branch.go1.17] archive/zip: don't panic on (*Reader).Open
Previously, opening a zip with (*Reader).Open could result in a panic if
the zip contained a file whose name was exclusively made up of slash
characters or ".." path elements.

Open could also panic if passed the empty string directly as an argument.

Now, any files in the zip whose name could not be made valid for
fs.FS.Open will be skipped, and no longer added to the fs.FS file list,
although they are still accessible through (*Reader).File.

Note that it was already the case that a file could be accessible from
(*Reader).Open with a name different from the one in (*Reader).File, as
the former is the cleaned name, while the latter is the original one.

Finally, made the actual panic site robust as a defense-in-depth measure.

Fixes CVE-2021-41772
Fixes #48252
Updates #48085

Co-authored-by: Filippo Valsorda <filippo@golang.org>
Change-Id: I6271a3f2892e7746f52e213b8eba9a1bba974678
Reviewed-on: https://go-review.googlesource.com/c/go/+/349770
Run-TryBot: Filippo Valsorda <filippo@golang.org>
Reviewed-by: Katie Hockman <katie@golang.org>
Reviewed-by: Filippo Valsorda <filippo@golang.org>
Trust: Katie Hockman <katie@golang.org>
Trust: Julie Qiu <julie@golang.org>
(cherry picked from commit b24687394b)
Reviewed-on: https://go-review.googlesource.com/c/go/+/360859
Trust: Dmitri Shuralyov <dmitshur@golang.org>
Run-TryBot: Dmitri Shuralyov <dmitshur@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
2021-11-03 16:57:44 +00:00
Dmitri Shuralyov
f9cb33c7c9 [release-branch.go1.17] net/http: update bundled golang.org/x/net/http2
Pull in approved backports to golang.org/x/net/http2:

	95aca89 set ContentLength to -1 for HEAD response with no Content-Length
	bd5b1b8 set Response.ContentLength to 0 when headers end stream
	27001ec don't abort half-closed streams on server connection close
	f0a8156 on write errors, close ClientConn before returning from RoundTrip
	9a182eb deflake TestTransportReqBodyAfterResponse_200
	821db7b close the Request's Body when aborting a stream
	028e125 return unexpected eof on empty response with non-zero content length
	5388f2f don't rely on system TCP buffer sizes in TestServer_MaxQueuedControlFrames
	fc298ce detect write-blocked PING frames
	e96ad84 avoid race in TestTransportReqBodyAfterResponse_403.
	7f15435 avoid clientConnPool panic when NewClientConn fails
	9572bae avoid extra GetConn trace call
	b04064c refactor request write flow
	7e165c9 remove PingTimeout from TestTransportPingWhenReading
	ef976fc fix Transport connection pool TOCTOU max concurrent stream bug
	1d9597c shut down idle Transport connections after protocol errors
	c173d09 remove check for read-after-close of request bodies
	466a463 fix race in DATA frame padding refund
	4028c5f avoid blocking while holding ClientConn.mu
	b91f72d fix off-by-one error in client check for max concurrent streams
	21e6c63 close request body after early RoundTrip failures
	e79adf9 limit client initial MAX_CONCURRENT_STREAMS
	c0c2bc5 make Transport not reuse conns after a stream protocol error
	14c0235 accept zero-length block fragments in HEADERS frames
	0d2c43c close the request body if needed
	5627bb0 reduce frameScratchBuffer caching aggressiveness
	c9f4fb0 also set "http/1.1" ALPN in ConfigureServer

By doing:

	$ go get -d golang.org/x/net@internal-branch.go1.17-vendor
	go get: upgraded golang.org/x/net v0.0.0-20210901185426-6d2eada6345e => v0.0.0-20211101194204-95aca89e93de
	$ go mod tidy
	$ go mod vendor
	$ go generate -run=bundle std

Fixes #49077.
Fixes #48823.
Fixes #48650.

Change-Id: Idb972ba5313080626b60b4111d52b80197364ff4
Reviewed-on: https://go-review.googlesource.com/c/go/+/359776
Trust: Dmitri Shuralyov <dmitshur@golang.org>
Run-TryBot: Dmitri Shuralyov <dmitshur@golang.org>
Reviewed-by: Damien Neil <dneil@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
2021-11-01 21:27:46 +00:00
Roland Shoemaker
4a842985bf [release-branch.go1.17] debug/macho: fail on invalid dynamic symbol table command
Fail out when loading a file that contains a dynamic symbol table
command that indicates a larger number of symbols than exist in the
loaded symbol table.

Thanks to Burak Çarıkçı - Yunus Yıldırım (CT-Zer0 Crypttech) for
reporting this issue.

Updates #48990
Fixes #48992
Fixes CVE-2021-41771

Change-Id: Ic3d6e6529241afcc959544b326b21b663262bad5
Reviewed-on: https://go-review.googlesource.com/c/go/+/355990
Reviewed-by: Julie Qiu <julie@golang.org>
Reviewed-by: Katie Hockman <katie@golang.org>
Reviewed-by: Emmanuel Odeke <emmanuel@orijtech.com>
Run-TryBot: Roland Shoemaker <roland@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Trust: Katie Hockman <katie@golang.org>
(cherry picked from commit 61536ec030)
Reviewed-on: https://go-review.googlesource.com/c/go/+/359455
Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org>
2021-10-29 19:42:51 +00:00
Russ Cox
f6f024f120 [release-branch.go1.17] cmd/go: update for //go:build lines
cmd/go has its own //go:build evaluator, which is needed for
patterns like 'all'. The code is a modified copy of some unexported
routines from the go/build package. Update it by copying those
again and re-modifying them. The modifications are primarily the new
func eval and also ignoring errors.

This CL will need to be backported to Go 1.17, or else Go 1.17
will break when faced with certain //go:build-only repos during
'go list all' or 'go mod tidy'.

For #41184.
Fixes #49198.

Change-Id: Ie0fe3caa8d49004935ecd76d7977f767fe50e317
Reviewed-on: https://go-review.googlesource.com/c/go/+/359355
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Bryan C. Mills <bcmills@google.com>
Reviewed-on: https://go-review.googlesource.com/c/go/+/359404
2021-10-28 21:17:17 +00:00
Richard Musiol
18b970277e [release-branch.go1.17] cmd/link: increase reserved space for passing env on wasm
On wasm, the wasm_exec.js helper passes the command line arguments and
environment variables via a reserved space in the wasm linear memory.
Increase this reserved space from 4096 to 8192 bytes so more environment
variables can fit into the limit.

Later, after https://golang.org/cl/350737 landed, we can switch to the
WASI interface for getting the arguments and environment. This would
remove the limit entirely.

Updates #49011.
Fixes #49154.

Change-Id: I48a6e952a97d33404ed692c98e9b49c5cd6b269b
Reviewed-on: https://go-review.googlesource.com/c/go/+/358194
Trust: Richard Musiol <neelance@gmail.com>
Run-TryBot: Richard Musiol <neelance@gmail.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Cherry Mui <cherryyz@google.com>
(cherry picked from commit 252324e879)
Reviewed-on: https://go-review.googlesource.com/c/go/+/359399
Trust: Dmitri Shuralyov <dmitshur@golang.org>
Run-TryBot: Dmitri Shuralyov <dmitshur@golang.org>
2021-10-28 18:01:34 +00:00
zhouguangyuan
91aa2f190a [release-branch.go1.17] cmd/link: disable weak reference in itab if build with "-linkshared"
When build with "-linkshared", we can't tell if the interface method will be used or not. It can be used in shared library.
This CL backport this fix to 1.17.

Fixes #49086

Change-Id: Iba12812f199b7679cf2fd41a304268d6d6dd03c6
Reviewed-on: https://go-review.googlesource.com/c/go/+/350189
Reviewed-by: Cherry Mui <cherryyz@google.com>
Run-TryBot: Cherry Mui <cherryyz@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Trust: Alexander Rakoczy <alex@golang.org>
(cherry picked from commit f687831e4c)
Reviewed-on: https://go-review.googlesource.com/c/go/+/357231
Trust: Ian Lance Taylor <iant@golang.org>
2021-10-28 16:34:40 +00:00
Michael Pratt
8bdb0b235a [release-branch.go1.17] runtime: consistently access pollDesc r/w Gs with atomics
Both netpollblock and netpollunblock read gpp using a non-atomic load.
When consuming a ready event, netpollblock clears gpp using a non-atomic
store, thus skipping a barrier.

Thus on systems with weak memory ordering, a sequence like so this is
possible:

             T1                                T2

1. netpollblock: read gpp -> pdReady
2. netpollblock: store gpp -> 0

                                 3. netpollunblock: read gpp -> pdReady
                                 4. netpollunblock: return

i.e., without a happens-before edge between (2) and (3), netpollunblock
may read the stale value of gpp.

Switch these access to use atomic loads and stores in order to create
these edges.

For ease of future maintainance, I've simply changed rg and wg to always
be accessed atomically, though I don't believe pollOpen or pollClose
require atomics today.

For #48925
Fixes #49010

Change-Id: I903ea667eea320277610b4f969129935731520c3
Reviewed-on: https://go-review.googlesource.com/c/go/+/355952
Trust: Michael Pratt <mpratt@google.com>
Run-TryBot: Michael Pratt <mpratt@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
Reviewed-by: David Chase <drchase@google.com>
(cherry picked from commit 1b072b3ed5)
Reviewed-on: https://go-review.googlesource.com/c/go/+/356369
2021-10-28 15:31:28 +00:00
Keith Randall
3a03ddf735 [release-branch.go1.17] cmd/compile: ensure constant shift amounts are in range for arm
Ensure constant shift amounts are in the range [0-31]. When shift amounts
are out of range, bad things happen. Shift amounts out of range occur
when lowering 64-bit shifts (we take an in-range shift s in [0-63] and
calculate s-32 and 32-s, both of which might be out of [0-31]).

The constant shift operations themselves still work, but their shift
amounts get copied unmolested to operations like ORshiftLL which use only
the low 5 bits. That changes an operation like <<100 which unconditionally
produces 0, to <<4, which doesn't.

Fixes #48479

Change-Id: I87363ef2b4ceaf3b2e316426064626efdfbb8ee3
Reviewed-on: https://go-review.googlesource.com/c/go/+/350969
Trust: Keith Randall <khr@golang.org>
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Cherry Mui <cherryyz@google.com>
(cherry picked from commit eff27e858b)
Reviewed-on: https://go-review.googlesource.com/c/go/+/351069
Reviewed-by: Austin Clements <austin@google.com>
2021-10-27 21:13:34 +00:00
Keith Randall
644555d34e [release-branch.go1.17] cmd/compile: fix simplification rules on arm/arm64
Fixes #48475

Change-Id: Ic1e918f916eae223a3b530a51a58f03031924670
Reviewed-on: https://go-review.googlesource.com/c/go/+/350913
Trust: Keith Randall <khr@golang.org>
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Cherry Mui <cherryyz@google.com>
Reviewed-on: https://go-review.googlesource.com/c/go/+/351071
Reviewed-by: Austin Clements <austin@google.com>
2021-10-27 20:42:29 +00:00
Jason A. Donenfeld
11b64b428b [release-branch.go1.17] syscall: do not use handle lists on windows when NoInheritHandles is true
If NoInheritHandles is passed, then we shouldn't attempt to do anything
with handle lists. Otherwise CreateProcess fails with invalid param,
because it's being told both to not inherit handles and to inherit
certain handles.

This commit fixes that by using the same logic for handle lists as it
does for enabling or disabling handle inheritance. It also adds a test
to make sure this doesn't regress again.

Updates #48040
Fixes #48075

Change-Id: I507261baeec263091738ab90157a991d917dc92f
Reviewed-on: https://go-review.googlesource.com/c/go/+/350416
Trust: Jason A. Donenfeld <Jason@zx2c4.com>
Run-TryBot: Jason A. Donenfeld <Jason@zx2c4.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Patrik Nyblom <pnyb@google.com>
2021-10-25 21:16:46 +00:00
Michael Anthony Knyszek
2ac3bdf378 [release-branch.go1.17] go1.17.2
Change-Id: Iffde23eabdc5c9474cd7f7b795cc187d78ca0f55
Reviewed-on: https://go-review.googlesource.com/c/go/+/354594
Trust: Michael Knyszek <mknyszek@google.com>
Run-TryBot: Michael Knyszek <mknyszek@google.com>
Reviewed-by: Heschi Kreinick <heschi@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
2021-10-07 18:11:41 +00:00
Michael Knyszek
4925e0766f [release-branch.go1.17] misc/wasm, cmd/link: do not let command line args overwrite global data
On Wasm, wasm_exec.js puts command line arguments at the beginning
of the linear memory (following the "zero page"). Currently there
is no limit for this, and a very long command line can overwrite
the program's data section. Prevent this by limiting the command
line to 4096 bytes, and in the linker ensuring the data section
starts at a high enough address (8192).

(Arguably our address assignment on Wasm is a bit confusing. This
is the minimum fix I can come up with.)

Thanks to Ben Lubar for reporting this issue.

Change by Cherry Mui <cherryyz@google.com>.

For #48797
Fixes #48800
Fixes CVE-2021-38297

Change-Id: I0f50fbb2a5b6d0d047e3c134a88988d9133e4ab3
Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/1205933
Reviewed-by: Roland Shoemaker <bracewell@google.com>
Reviewed-by: Than McIntosh <thanm@google.com>
Reviewed-on: https://go-review.googlesource.com/c/go/+/354592
Trust: Michael Knyszek <mknyszek@google.com>
Reviewed-by: Heschi Kreinick <heschi@google.com>
2021-10-07 14:54:47 +00:00
Cuong Manh Le
b18ba59aaf [release-branch.go1.17] cmd/compile: fold handling OCONV logic to separate function
So next CL can re-use the logic to perform checkptr instrumentation.

For #48561

Change-Id: I3241e9c3c84da04db71fd1d4fd83cb76b2e18521
Reviewed-on: https://go-review.googlesource.com/c/go/+/345435
Trust: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
(cherry picked from commit 8fad81cd62)
Reviewed-on: https://go-review.googlesource.com/c/go/+/354352
Trust: Ian Lance Taylor <iant@golang.org>
Run-TryBot: Ian Lance Taylor <iant@golang.org>
2021-10-06 22:28:59 +00:00
Jay Conrod
04242ac88f [release-branch.go1.17] cmd/go: write go.mod requirements more consistently for go 1.17+
If go.mod declares 1.17 or higher, when the go command rewrites go.mod
(for example, after 'go mod tidy'), it will be more consistent about
moving requirements in two blocks, one containing only direct
requirements, and one containing only indirect requirements.

The go command will not move requirements into or out of a block with
comments. It may still update versions and "// indirect" comments, and
it may delete unneeded requirements though.

Fixes #47756

Change-Id: Ia6fb3e302be53097893abf01aa7cea60ac7b069a
Reviewed-on: https://go-review.googlesource.com/c/go/+/343432
Trust: Jay Conrod <jayconrod@google.com>
Run-TryBot: Jay Conrod <jayconrod@google.com>
Reviewed-by: Bryan C. Mills <bcmills@google.com>
(cherry picked from commit 3c764babe7)
Reviewed-on: https://go-review.googlesource.com/c/go/+/351465
TryBot-Result: Go Bot <gobot@golang.org>
2021-09-28 20:30:45 +00:00
Ian Lance Taylor
c5c1d069da [release-branch.go1.17] text/template: initialize template before locking it
For #39807
For #48436
Fixes #48444

Change-Id: I75f82fd8738dd2f11f0c69b1230e1be1abc36024
Reviewed-on: https://go-review.googlesource.com/c/go/+/350730
Trust: Ian Lance Taylor <iant@golang.org>
Trust: Daniel Martí <mvdan@mvdan.cc>
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Daniel Martí <mvdan@mvdan.cc>
(cherry picked from commit ba1c52d7d7)
Reviewed-on: https://go-review.googlesource.com/c/go/+/351115
2021-09-23 21:18:37 +00:00
Ian Lance Taylor
abc4f092ac [release-branch.go1.17] runtime: in adjustTimers back up as far as necessary
When the adjustTimers function removed a timer it assumed it was
sufficient to continue the heap traversal at that position.
However, in some cases a timer will be moved to an earlier
position in the heap. If that timer is timerModifiedEarlier,
that can leave timerModifiedEarliest not correctly representing
the earlier such timer.

Fix the problem by restarting the heap traversal at the earliest
changed position.

For #47762
Fixes #47859

Change-Id: I152bbe62793ee40a680baf49967bcb89b1f94764
Reviewed-on: https://go-review.googlesource.com/c/go/+/343882
Trust: Ian Lance Taylor <iant@golang.org>
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
(cherry picked from commit 2da3375e9b)
Reviewed-on: https://go-review.googlesource.com/c/go/+/350001
2021-09-15 23:28:10 +00:00
korzhao
e79c297fa8 [release-branch.go1.17] time: propagate "," separator for fractional seconds into Format
In CL 300996 that fixed issue #6189, we made Parse recognize
"," as a separator for fractional seconds.
However, we didn't modify Format to propagate the separator
verbatim from Parse. Without this change, we break prior
functionality that relied on a comma being used in Format.

For #48037
Fixes #48177

Change-Id: I6565a25e8657ca3747a58b25acba58f27cdcddc0
Reviewed-on: https://go-review.googlesource.com/c/go/+/345438
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Reviewed-by: Emmanuel Odeke <emmanuel@orijtech.com>
Trust: Cherry Mui <cherryyz@google.com>
(cherry picked from commit e1c3f2158f)
Reviewed-on: https://go-review.googlesource.com/c/go/+/350149
Trust: Ian Lance Taylor <iant@golang.org>
2021-09-15 21:59:48 +00:00
Than McIntosh
21a4e67ad5 [release-branch.go1.17] go1.17.1
Change-Id: I05758c4bff332dbb71dbfb1f5743aeaf0a1b39d9
Reviewed-on: https://go-review.googlesource.com/c/go/+/348813
Run-TryBot: Than McIntosh <thanm@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Cherry Mui <cherryyz@google.com>
Trust: Than McIntosh <thanm@google.com>
2021-09-09 15:27:21 +00:00
Bryan C. Mills
328cf2e8b2 [release-branch.go1.17] cmd/go/internal/modload: scan dependencies of root paths when raising version limits in editRequirements
Updates #47979
Fixes #48156

Change-Id: I1d9d854cda1378e20c70e6c6789b77e42e467ca7
Reviewed-on: https://go-review.googlesource.com/c/go/+/347290
Trust: Bryan C. Mills <bcmills@google.com>
Run-TryBot: Bryan C. Mills <bcmills@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Jay Conrod <jayconrod@google.com>
(cherry picked from commit 409434d623)
Reviewed-on: https://go-review.googlesource.com/c/go/+/348411
2021-09-08 20:41:51 +00:00
Damien Neil
fcce86c4cf [release-branch.go1.17] all: update golang.org/x/net to pull in CL 346890
For #47692.

Change-Id: I40d5a3ed245b99de5e82e336f955c60b58880cdb
Reviewed-on: https://go-review.googlesource.com/c/go/+/347009
Trust: Damien Neil <dneil@google.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
Run-TryBot: Cherry Mui <cherryyz@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
2021-09-01 22:54:04 +00:00
Robert Griesemer
36c171763e [release-branch.go1.17] go/types: don't override x.mode before using it
Changing the mode of x before using the old value is clearly wrong.
And x is not needed anymore afterward so besides being misplaced,
the assignment is not needed in the first place.

Tested manually as it's a bit complicated to set up a test.

Fixes #47854.

Change-Id: I06f1fa9443eb98009b4276f566d557fd52f1d6d3
Reviewed-on: https://go-review.googlesource.com/c/go/+/343809
Trust: Robert Griesemer <gri@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
(cherry picked from commit e17439e087)
Reviewed-on: https://go-review.googlesource.com/c/go/+/347149
Run-TryBot: Robert Griesemer <gri@golang.org>
Run-TryBot: Robert Findley <rfindley@google.com>
Reviewed-by: Robert Findley <rfindley@google.com>
Trust: Robert Findley <rfindley@google.com>
Trust: Cherry Mui <cherryyz@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
2021-09-01 22:32:32 +00:00
Rob Findley
678b07d5e5 [release-branch.go1.17] go/types: fix panic with nil package name
This is a straightforward port of CL 320490 to go/types.

Fixes #48082

Change-Id: I763c806c777f926a563d8f9384764e5b3f7f083c
Reviewed-on: https://go-review.googlesource.com/c/go/+/324732
Trust: Robert Findley <rfindley@google.com>
Run-TryBot: Robert Findley <rfindley@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
(cherry picked from commit e32fab145b)
Reviewed-on: https://go-review.googlesource.com/c/go/+/347071
2021-09-01 22:31:06 +00:00
Jay Conrod
14c9b1e00b [release-branch.go1.17] cmd/go: ensure 'go get -u' can upgrade pruned (1.17+) modules
Fixes #47857

Change-Id: I981a31ba4ff716570ac4c6f35b289fa480faa5bb
Reviewed-on: https://go-review.googlesource.com/c/go/+/343879
Trust: Jay Conrod <jayconrod@google.com>
Run-TryBot: Jay Conrod <jayconrod@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Michael Matloob <matloob@golang.org>
Reviewed-by: Bryan C. Mills <bcmills@google.com>
(cherry picked from commit bdc1bef8a0)
Reviewed-on: https://go-review.googlesource.com/c/go/+/346211
2021-09-01 17:15:36 +00:00
Tobias Klauser
c35f8a37d9 [release-branch.go1.17] crypto/rand, internal/syscall/unix: don't use getentropy on iOS
CL 302489 switched crypto/rand to use getentropy on darwin, however this
function is not available on iOS. Enable getentropy only on macOS and
disable it on iOS.

Fixes #47814

Change-Id: Ib7ba5d77346aee87904bb93d60cacc845f5c0089
Reviewed-on: https://go-review.googlesource.com/c/go/+/343609
Trust: Tobias Klauser <tobias.klauser@gmail.com>
Run-TryBot: Tobias Klauser <tobias.klauser@gmail.com>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
(cherry picked from commit 7007431374)
Reviewed-on: https://go-review.googlesource.com/c/go/+/343989
2021-09-01 17:08:11 +00:00
Cherry Mui
47a57bc4f0 [release-branch.go1.17] cmd/link: do not use GO_LDSO when cross compile
GO_LDSO is a setting that is set when the toolchain is build. It
only makes sense to use it on the host platform. Do not use it
when targetting a different platform.

In the past it was not a problem as GO_LDSO was almost always
unset. Now, with CL 301989 it is almost always set (maybe we want
to revisit it).

Updates #47760.
Fixes #47782.

Change-Id: I2704b9968781f46e2d2f8624090db19689b1a32f
Reviewed-on: https://go-review.googlesource.com/c/go/+/343010
Trust: Cherry Mui <cherryyz@google.com>
Run-TryBot: Cherry Mui <cherryyz@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
(cherry picked from commit ddfcc02352)
Reviewed-on: https://go-review.googlesource.com/c/go/+/343309
2021-09-01 17:06:03 +00:00
Keith Randall
2d97a87287 [release-branch.go1.17] cmd/compile: allow embed into any byte slice type
Fixes #47754

Change-Id: Ia21ea9a67f36a3edfef1b299ae4f3b00c306cd68
Reviewed-on: https://go-review.googlesource.com/c/go/+/345092
Trust: Keith Randall <khr@golang.org>
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2021-09-01 16:49:05 +00:00
Cuong Manh Le
3969694203 [release-branch.go1.17] cmd/compile: fix method expression lookup during import
CL 309831 fixed importing of method expressions, by re-using the same
code already have for ODOTMETH. But that code does not work with
embedded field.

To fix this, we need to calculate all methods of the receiver base type
of method expression, before looking up the selection.

Fixes #48102

Change-Id: Ia244d36a3ed0f989735eb57becdfa70a81912f57
Reviewed-on: https://go-review.googlesource.com/c/go/+/346489
Trust: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Reviewed-on: https://go-review.googlesource.com/c/go/+/346670
Reviewed-by: Keith Randall <khr@golang.org>
2021-09-01 16:46:29 +00:00
Roland Shoemaker
1dd24caf08 [release-branch.go1.17] archive/zip: prevent preallocation check from overflowing
If the indicated directory size in the archive header is so large that
subtracting it from the archive size overflows a uint64, the check that
the indicated number of files in the archive can be effectively
bypassed. Prevent this from happening by checking that the indicated
directory size is less than the size of the archive.

Thanks to the OSS-Fuzz project for discovering this issue and to
Emmanuel Odeke for reporting it.

Fixes #47986
Updates #47801
Fixes CVE-2021-39293

Change-Id: Ifade26b98a40f3b37398ca86bd5252d12394dd24
Reviewed-on: https://go-review.googlesource.com/c/go/+/343434
Trust: Roland Shoemaker <roland@golang.org>
Run-TryBot: Roland Shoemaker <roland@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Russ Cox <rsc@golang.org>
(cherry picked from commit bacbc33439)
Reviewed-on: https://go-review.googlesource.com/c/go/+/345410
Reviewed-by: Emmanuel Odeke <emmanuel@orijtech.com>
Run-TryBot: Emmanuel Odeke <emmanuel@orijtech.com>
Trust: Cherry Mui <cherryyz@google.com>
2021-09-01 16:41:15 +00:00
Michael Anthony Knyszek
ec5170397c [release-branch.go1.17] go1.17
Change-Id: Ie59feb7f043574c7db4c7f14184603442638e4c0
Reviewed-on: https://go-review.googlesource.com/c/go/+/342470
Run-TryBot: Michael Knyszek <mknyszek@google.com>
Trust: Michael Knyszek <mknyszek@google.com>
Reviewed-by: Heschi Kreinick <heschi@google.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
2021-08-16 16:23:06 +00:00
Jeff Wentworth
fdd6dfd507 [release-branch.go1.17] sync/atomic: fix documentation for CompareAndSwap
The documentation for CompareAndSwap atomic/value incorrectly labelled
the function as CompareAndSwapPointer. This PR fixes that.

Updates #47699.
Fixes #47703.

Change-Id: I6db08fdfe166570b775248fd24550f5d28e3434e
GitHub-Last-Rev: 41f7870792
GitHub-Pull-Request: golang/go#47700
Reviewed-on: https://go-review.googlesource.com/c/go/+/342210
Reviewed-by: Keith Randall <khr@golang.org>
Reviewed-by: Daniel Martí <mvdan@mvdan.cc>
Trust: Daniel Martí <mvdan@mvdan.cc>
Run-TryBot: Daniel Martí <mvdan@mvdan.cc>
TryBot-Result: Go Bot <gobot@golang.org>
(cherry picked from commit 0a0a160d4d)
Reviewed-on: https://go-review.googlesource.com/c/go/+/342329
Trust: Dmitri Shuralyov <dmitshur@golang.org>
Run-TryBot: Dmitri Shuralyov <dmitshur@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2021-08-15 22:50:19 +00:00
Michael Pratt
f7b9470992 [release-branch.go1.17] runtime: drop SIGPROF while in ARM < 7 kernel helpers
On Linux ARMv6 and below runtime/internal/atomic.Cas calls into a kernel
cas helper at a fixed address. If a SIGPROF arrives while executing the
kernel helper, the sigprof lostAtomic logic will miss that we are
potentially in the spinlock critical section, which could cause
a deadlock when using atomics later in sigprof.

For #47505
Fixes #47688

Change-Id: If8ba0d0fc47e45d4e6c68eca98fac4c6ed4e43c1
Reviewed-on: https://go-review.googlesource.com/c/go/+/341889
Trust: Michael Pratt <mpratt@google.com>
Run-TryBot: Michael Pratt <mpratt@google.com>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
(cherry picked from commit 20a620fd9f)
Reviewed-on: https://go-review.googlesource.com/c/go/+/341890
2021-08-13 16:34:25 +00:00
Russ Cox
4397d66bdd [release-branch.go1.17] time: fix docs for new comma layouts
The current text is slightly inaccurate. Make it more correct.

Change-Id: Iebe0051b74649d13982d7eefe3697f9e69c9b75d
Reviewed-on: https://go-review.googlesource.com/c/go/+/340449
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
Reviewed-by: Jay Conrod <jayconrod@google.com>
Reviewed-by: Damien Neil <dneil@google.com>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-on: https://go-review.googlesource.com/c/go/+/341949
Trust: Dmitri Shuralyov <dmitshur@golang.org>
Run-TryBot: Dmitri Shuralyov <dmitshur@golang.org>
Reviewed-by: Russ Cox <rsc@golang.org>
2021-08-13 16:26:40 +00:00
Dmitri Shuralyov
eb5a7b5050 [release-branch.go1.17] all: merge master (5805efc) into release-branch.go1.17
Merge List:

+ 2021-08-12 5805efc78e doc/go1.17: remove draft notice
+ 2021-08-12 39634e7dae CONTRIBUTORS: update for the Go 1.17 release
+ 2021-08-12 095bb790e1 os/exec: re-enable LookPathTest/16
+ 2021-08-11 dea23e9ca8 src/make.*: make --no-clean flag a no-op that prints a warning
+ 2021-08-11 d4c0ed26ac doc/go1.17: linker passes -I to extld as -Wl,--dynamic-linker
+ 2021-08-10 1f9c9d8530 doc: use "high address/low address" instead of "top/bottom"
+ 2021-08-09 f1dce319ff cmd/go: with -mod=vendor, don't panic if there are duplicate requirements
+ 2021-08-09 7aeaad5c86 runtime/cgo: when using msan explicitly unpoison cgoCallers
+ 2021-08-08 507cc341ec doc: add example for conversion from slice expressions to array ptr
+ 2021-08-07 891547e2d4 doc/go1.17: fix a typo introduced in CL 335135
+ 2021-08-06 8eaf4d16bc make.bash: do not overwrite GO_LDSO if already set
+ 2021-08-06 63b968f4f8 doc/go1.17: clarify Modules changes
+ 2021-08-06 70546f6404 runtime: allow arm64 SEH to be called if illegal instruction
+ 2021-08-05 fd45e267c2 runtime: warn that KeepAlive is not an unsafe.Pointer workaround
+ 2021-08-04 6e738868a7 net/http: speed up and deflake TestCancelRequestWhenSharingConnection
+ 2021-08-02 8a7ee4c51e io/fs: don't use absolute path in DirEntry.Name doc

Change-Id: Ie9ce48bf4e99457cde966c5f972b04140468fcf0
2021-08-12 14:04:53 -04:00
Alexander Rakoczy
72ab3ff68b [release-branch.go1.17] go1.17rc2
Change-Id: I1f1ada15d7365db3e48599fbaddd6a65a8e5d06c
Reviewed-on: https://go-review.googlesource.com/c/go/+/339130
Run-TryBot: Alexander Rakoczy <alex@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Trust: Alexander Rakoczy <alex@golang.org>
Reviewed-by: David Chase <drchase@google.com>
2021-08-02 17:57:22 +00:00
Alexander Rakoczy
c3ccb77d1e [release-branch.go1.17] all: merge master (b8ca6e5) into release-branch.go1.17
Merge List:

+ 2021-07-31 b8ca6e59ed all: gofmt
+ 2021-07-30 b7a85e0003 net/http/httputil: close incoming ReverseProxy request body
+ 2021-07-29 70fd4e47d7 runtime: avoid possible preemption when returning from Go to C
+ 2021-07-28 9eee0ed439 cmd/go: fix go.mod file name printed in error messages for replacements
+ 2021-07-28 b39e0f461c runtime: don't crash on nil pointers in checkptrAlignment
+ 2021-07-27 7cd10c1149 cmd/go: use .mod instead of .zip to determine if version has go.mod file
+ 2021-07-27 c8cf0f74e4 cmd/go: add missing flag in UsageLine
+ 2021-07-27 7ba8e796c9 testing: clarify T.Name returns a distinct name of the running test
+ 2021-07-27 33ff155970 go/types: preserve untyped constants on the RHS of a shift expression
+ 2021-07-26 840e583ff3 runtime: correct variable name in comment
+ 2021-07-26 bfbb288574 runtime: remove adjustTimers counter
+ 2021-07-26 9c81fd53b3 cmd/vet: add missing copyright header
+ 2021-07-26 ecaa6816bf doc: clarify non-nil zero length slice to array pointer conversion
+ 2021-07-26 1868f8296e crypto/x509: update iOS bundled roots to version 55188.120.1.0.1
+ 2021-07-25 849b791129 spec: use consistent capitalization for rune literal hex constants
+ 2021-07-23 0914646ab9 doc/1.17: fix two dead rfc links
+ 2021-07-22 052da5717e cmd/compile: do not change field offset in ABI analysis
+ 2021-07-22 798ec73519 runtime: don't clear timerModifiedEarliest if adjustTimers is 0
+ 2021-07-22 fdb45acd1f runtime: move mem profile sampling into m-acquired section
+ 2021-07-21 3e48c0381f reflect: add missing copyright header
+ 2021-07-21 48c88f1b1b reflect: add Value.CanConvert
+ 2021-07-20 9e26569293 cmd/go: don't add C compiler ID to hash for standard library
+ 2021-07-20 d568e6e075 runtime/debug: skip TestPanicOnFault on netbsd/arm
+ 2021-07-19 c8f4e6152d spec: correct example comment in Conversions from slice to array
+ 2021-07-19 1d91551b73 time: correct typo in documentation for UnixMicro
+ 2021-07-19 404127c30f cmd/compile: fix off-by-one error in traceback argument counting
+ 2021-07-19 6298cfe672 cmd/compile: fix typo in fatal message of builtinCall
+ 2021-07-19 49402bee36 cmd/{compile,link}: fix bug in map.zero handling
+ 2021-07-18 a66190ecee test/bench/go1: fix size for RegexpMatchMedium_32
+ 2021-07-18 650fc2117a text/scanner: use Go convention in Position doc comment
+ 2021-07-16 aa4e0f528e net/http:  correct capitalization in cancelTimeBody comment
+ 2021-07-15 0941dbca6a testing: clarify in docs that TestMain is advanced
+ 2021-07-15 69728ead87 cmd/go: update error messages in tests to match CL 332573
+ 2021-07-15 c1cc9f9c3d cmd/compile: fix lookup package of redeclared dot import symbol
+ 2021-07-15 21a04e3335 doc/go1.17: mention GOARCH=loong64
+ 2021-07-14 2b00a54baf go/build, runtime/internal/sys: reserve GOARCH=loong64
+ 2021-07-14 60ddf42b46 cmd/go: change link in error message from /wiki to /doc.
+ 2021-07-13 d8f348a589 cmd/go: remove a duplicated word from 'go help mod graph'

Change-Id: I63a540ba823bcbde7249348999ac5a7d9908b531
2021-08-02 11:56:53 -04:00
Dmitri Shuralyov
c3b47cb598 [release-branch.go1.17] update codereview.cfg for release-branch.go1.17
The initial "branch: master" configuration was inherited from when
the release-branch.go1.17 branch was branched off the master branch.
Update the "branch" key, otherwise a modern git-codereview will mail
CLs to the wrong branch.

We can set "parent-branch" so that 'git codereview sync-branch' works
to merge latest master into release-branch.go1.17, something we want
to do for subsequent RCs, maybe up to the final release. (At some point
the release freeze will end and tree will open for Go 1.18 development,
so we'll be switching to using cherry-picks only. Having parent-branch
will not be useful then, but I think harmless.)

Change-Id: I36ab977eaeb52bc0a84cc59e807572054f54c789
Reviewed-on: https://go-review.googlesource.com/c/go/+/334376
Reviewed-by: Cherry Mui <cherryyz@google.com>
Reviewed-by: Heschi Kreinick <heschi@google.com>
Trust: Dmitri Shuralyov <dmitshur@golang.org>
2021-07-13 22:45:26 +00:00
Cherry Mui
ddfd72f7d1 [release-branch.go1.17] go1.17rc1
Change-Id: Idc207e34c54b9bff0ae59348e4bc97474b1c11d2
Reviewed-on: https://go-review.googlesource.com/c/go/+/334254
Run-TryBot: Cherry Mui <cherryyz@google.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Trust: Cherry Mui <cherryyz@google.com>
2021-07-13 17:12:38 +00:00
Cherry Mui
d6f4d9a2be [release-branch.go1.17] all: merge master into release-branch.go1.17
a98589711d crypto/tls: test key type when casting
cfbd73ba33 doc/go1.17: editing pass over the "Compiler" section
ab4085ce84 runtime/pprof: call runtime.GC twice in memory profile test

Change-Id: I5b19d559629353886752e2a73ce8f37f983772df
2021-07-13 11:17:41 -04:00
117 changed files with 3452 additions and 1734 deletions

1
VERSION Normal file
View File

@@ -0,0 +1 @@
go1.17.5

View File

@@ -1 +1,2 @@
branch: master
branch: release-branch.go1.17
parent-branch: master

View File

@@ -753,9 +753,9 @@ func Foo() bool {
<p><!-- CL 311572 -->
The new
<a href="/pkg/database/sql/#NullInt16"><code>NullInt16</code></a>
and
<a href="/pkg/database/sql/#NullByte"><code>NullByte</code></a>
<a href="/pkg/database/sql/#NullInt16"><code>NullInt16</code></a>
and
<a href="/pkg/database/sql/#NullByte"><code>NullByte</code></a>
structs represent the int16 and byte values that may be null. These can be used as
destinations of the <a href="/pkg/database/sql/#Scan"><code>Scan</code></a> method,
similar to NullString.
@@ -1205,11 +1205,11 @@ func Foo() bool {
<p><!-- CL 300996 -->
The package now accepts comma "," as a separator for fractional seconds when parsing and formatting time.
The following time formats are now accepted:
For example, the following time layouts are now accepted:
<ul>
<li>2006-01-02 14:06:03,999999999 -0700 MST</li>
<li>Mon Jan _2 14:06:03,120007 2006</li>
<li>Mon Jan 2 14:06:03,120007 2006</li>
<li>2006-01-02 15:04:05,999999999 -0700 MST</li>
<li>Mon Jan _2 15:04:05,000000 2006</li>
<li>Monday, January 2 15:04:05,000 2006</li>
</ul>
</p>

View File

@@ -265,7 +265,7 @@ func TestIssue25756(t *testing.T) {
// Test with main using -buildmode=pie with plugin for issue #43228
func TestIssue25756pie(t *testing.T) {
if os.Getenv("GO_BUILDER_NAME") == "darwin-arm64-11_0-toothrot" {
if os.Getenv("GO_BUILDER_NAME") == "darwin-arm64-11_0-toothrot" || os.Getenv("GO_BUILDER_NAME") == "darwin-arm64-12_0-toothrot" {
t.Skip("broken on darwin/arm64 builder in sharded mode; see issue 46239")
}

View File

@@ -1070,3 +1070,11 @@ func TestIssue44031(t *testing.T) {
goCmd(t, "install", "-buildmode=shared", "-linkshared", "./issue44031/b")
goCmd(t, "run", "-linkshared", "./issue44031/main")
}
// Test that we use a variable from shared libraries (which implement an
// interface in shared libraries.). A weak reference is used in the itab
// in main process. It can cause unreacheble panic. See issue 47873.
func TestIssue47873(t *testing.T) {
goCmd(t, "install", "-buildmode=shared", "-linkshared", "./issue47837/a")
goCmd(t, "run", "-linkshared", "./issue47837/main")
}

View File

@@ -0,0 +1,19 @@
// Copyright 2021 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 a
type A interface {
M()
}
//go:noinline
func TheFuncWithArgA(a A) {
a.M()
}
type ImplA struct{}
//go:noinline
func (A *ImplA) M() {}

View File

@@ -0,0 +1,14 @@
// Copyright 2021 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 main
import (
"testshared/issue47837/a"
)
func main() {
var vara a.ImplA
a.TheFuncWithArgA(&vara)
}

View File

@@ -567,6 +567,13 @@
offset += 8;
});
// The linker guarantees global data starts from at least wasmMinDataAddr.
// Keep in sync with cmd/link/internal/ld/data.go:wasmMinDataAddr.
const wasmMinDataAddr = 4096 + 8192;
if (offset >= wasmMinDataAddr) {
throw new Error("total length of command line and environment variables exceeds limit");
}
this._inst.exports.run(argc, argv);
if (this.exited) {
this._resolveExitPromise();

View File

@@ -102,7 +102,7 @@ func (z *Reader) init(r io.ReaderAt, size int64) error {
// indicate it contains up to 1 << 128 - 1 files. Since each file has a
// header which will be _at least_ 30 bytes we can safely preallocate
// if (data size / 30) >= end.directoryRecords.
if (uint64(size)-end.directorySize)/30 >= end.directoryRecords {
if end.directorySize < uint64(size) && (uint64(size)-end.directorySize)/30 >= end.directoryRecords {
z.File = make([]*File, 0, end.directoryRecords)
}
z.Comment = end.comment
@@ -741,6 +741,9 @@ func (r *Reader) initFileList() {
for _, file := range r.File {
isDir := len(file.Name) > 0 && file.Name[len(file.Name)-1] == '/'
name := toValidName(file.Name)
if name == "" {
continue
}
for dir := path.Dir(name); dir != "."; dir = path.Dir(dir) {
dirs[dir] = true
}
@@ -782,8 +785,11 @@ func fileEntryLess(x, y string) bool {
func (r *Reader) Open(name string) (fs.File, error) {
r.initFileList()
if !fs.ValidPath(name) {
return nil, &fs.PathError{Op: "open", Path: name, Err: fs.ErrInvalid}
}
e := r.openLookup(name)
if e == nil || !fs.ValidPath(name) {
if e == nil {
return nil, &fs.PathError{Op: "open", Path: name, Err: fs.ErrNotExist}
}
if e.isDir {
@@ -797,7 +803,7 @@ func (r *Reader) Open(name string) (fs.File, error) {
}
func split(name string) (dir, elem string, isDir bool) {
if name[len(name)-1] == '/' {
if len(name) > 0 && name[len(name)-1] == '/' {
isDir = true
name = name[:len(name)-1]
}

View File

@@ -13,6 +13,7 @@ import (
"io/fs"
"os"
"path/filepath"
"reflect"
"regexp"
"strings"
"testing"
@@ -1202,6 +1203,15 @@ func TestCVE202127919(t *testing.T) {
if err != nil {
t.Errorf("Error reading file: %v", err)
}
if len(r.File) != 1 {
t.Fatalf("No entries in the file list")
}
if r.File[0].Name != "../test.txt" {
t.Errorf("Unexpected entry name: %s", r.File[0].Name)
}
if _, err := r.File[0].Open(); err != nil {
t.Errorf("Error opening file: %v", err)
}
}
func TestReadDataDescriptor(t *testing.T) {
@@ -1384,3 +1394,139 @@ func TestCVE202133196(t *testing.T) {
t.Errorf("Archive has unexpected number of files, got %d, want 5", len(r.File))
}
}
func TestCVE202139293(t *testing.T) {
// directory size is so large, that the check in Reader.init
// overflows when subtracting from the archive size, causing
// the pre-allocation check to be bypassed.
data := []byte{
0x50, 0x4b, 0x06, 0x06, 0x05, 0x06, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x4b,
0x06, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x50, 0x4b, 0x05, 0x06, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x4b,
0x06, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x50, 0x4b, 0x05, 0x06, 0x00, 0x31, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
0xff, 0x50, 0xfe, 0x00, 0xff, 0x00, 0x3a, 0x00, 0x00, 0x00, 0xff,
}
_, err := NewReader(bytes.NewReader(data), int64(len(data)))
if err != ErrFormat {
t.Fatalf("unexpected error, got: %v, want: %v", err, ErrFormat)
}
}
func TestCVE202141772(t *testing.T) {
// Archive contains a file whose name is exclusively made up of '/', '\'
// characters, or "../", "..\" paths, which would previously cause a panic.
//
// Length Method Size Cmpr Date Time CRC-32 Name
// -------- ------ ------- ---- ---------- ----- -------- ----
// 0 Stored 0 0% 08-05-2021 18:32 00000000 /
// 0 Stored 0 0% 09-14-2021 12:59 00000000 //
// 0 Stored 0 0% 09-14-2021 12:59 00000000 \
// 11 Stored 11 0% 09-14-2021 13:04 0d4a1185 /test.txt
// -------- ------- --- -------
// 11 11 0% 4 files
data := []byte{
0x50, 0x4b, 0x03, 0x04, 0x0a, 0x00, 0x00, 0x08,
0x00, 0x00, 0x06, 0x94, 0x05, 0x53, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x2f, 0x50,
0x4b, 0x03, 0x04, 0x0a, 0x00, 0x00, 0x00, 0x00,
0x00, 0x78, 0x67, 0x2e, 0x53, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x02, 0x00, 0x00, 0x00, 0x2f, 0x2f, 0x50,
0x4b, 0x03, 0x04, 0x0a, 0x00, 0x00, 0x00, 0x00,
0x00, 0x78, 0x67, 0x2e, 0x53, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x01, 0x00, 0x00, 0x00, 0x5c, 0x50, 0x4b,
0x03, 0x04, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00,
0x91, 0x68, 0x2e, 0x53, 0x85, 0x11, 0x4a, 0x0d,
0x0b, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00,
0x09, 0x00, 0x00, 0x00, 0x2f, 0x74, 0x65, 0x73,
0x74, 0x2e, 0x74, 0x78, 0x74, 0x68, 0x65, 0x6c,
0x6c, 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64,
0x50, 0x4b, 0x01, 0x02, 0x14, 0x03, 0x0a, 0x00,
0x00, 0x08, 0x00, 0x00, 0x06, 0x94, 0x05, 0x53,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
0xed, 0x41, 0x00, 0x00, 0x00, 0x00, 0x2f, 0x50,
0x4b, 0x01, 0x02, 0x3f, 0x00, 0x0a, 0x00, 0x00,
0x00, 0x00, 0x00, 0x78, 0x67, 0x2e, 0x53, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x02, 0x00, 0x24, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00,
0x00, 0x1f, 0x00, 0x00, 0x00, 0x2f, 0x2f, 0x0a,
0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
0x00, 0x18, 0x00, 0x93, 0x98, 0x25, 0x57, 0x25,
0xa9, 0xd7, 0x01, 0x93, 0x98, 0x25, 0x57, 0x25,
0xa9, 0xd7, 0x01, 0x93, 0x98, 0x25, 0x57, 0x25,
0xa9, 0xd7, 0x01, 0x50, 0x4b, 0x01, 0x02, 0x3f,
0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78,
0x67, 0x2e, 0x53, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x20, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00,
0x00, 0x5c, 0x0a, 0x00, 0x20, 0x00, 0x00, 0x00,
0x00, 0x00, 0x01, 0x00, 0x18, 0x00, 0x93, 0x98,
0x25, 0x57, 0x25, 0xa9, 0xd7, 0x01, 0x93, 0x98,
0x25, 0x57, 0x25, 0xa9, 0xd7, 0x01, 0x93, 0x98,
0x25, 0x57, 0x25, 0xa9, 0xd7, 0x01, 0x50, 0x4b,
0x01, 0x02, 0x3f, 0x00, 0x0a, 0x00, 0x00, 0x00,
0x00, 0x00, 0x91, 0x68, 0x2e, 0x53, 0x85, 0x11,
0x4a, 0x0d, 0x0b, 0x00, 0x00, 0x00, 0x0b, 0x00,
0x00, 0x00, 0x09, 0x00, 0x24, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
0x5e, 0x00, 0x00, 0x00, 0x2f, 0x74, 0x65, 0x73,
0x74, 0x2e, 0x74, 0x78, 0x74, 0x0a, 0x00, 0x20,
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x18,
0x00, 0xa9, 0x80, 0x51, 0x01, 0x26, 0xa9, 0xd7,
0x01, 0x31, 0xd1, 0x57, 0x01, 0x26, 0xa9, 0xd7,
0x01, 0xdf, 0x48, 0x85, 0xf9, 0x25, 0xa9, 0xd7,
0x01, 0x50, 0x4b, 0x05, 0x06, 0x00, 0x00, 0x00,
0x00, 0x04, 0x00, 0x04, 0x00, 0x31, 0x01, 0x00,
0x00, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00,
}
r, err := NewReader(bytes.NewReader([]byte(data)), int64(len(data)))
if err != nil {
t.Fatalf("Error reading the archive: %v", err)
}
entryNames := []string{`/`, `//`, `\`, `/test.txt`}
var names []string
for _, f := range r.File {
names = append(names, f.Name)
if _, err := f.Open(); err != nil {
t.Errorf("Error opening %q: %v", f.Name, err)
}
if _, err := r.Open(f.Name); err == nil {
t.Errorf("Opening %q with fs.FS API succeeded", f.Name)
}
}
if !reflect.DeepEqual(names, entryNames) {
t.Errorf("Unexpected file entries: %q", names)
}
if _, err := r.Open(""); err == nil {
t.Errorf("Opening %q with fs.FS API succeeded", "")
}
if _, err := r.Open("test.txt"); err != nil {
t.Errorf("Error opening %q with fs.FS API: %v", "test.txt", err)
}
dirEntries, err := fs.ReadDir(r, ".")
if err != nil {
t.Fatalf("Error reading the root directory: %v", err)
}
if len(dirEntries) != 1 || dirEntries[0].Name() != "test.txt" {
t.Errorf("Unexpected directory entries")
for _, dirEntry := range dirEntries {
_, err := r.Open(dirEntry.Name())
t.Logf("%q (Open error: %v)", dirEntry.Name(), err)
}
t.FailNow()
}
info, err := dirEntries[0].Info()
if err != nil {
t.Fatalf("Error reading info entry: %v", err)
}
if name := info.Name(); name != "test.txt" {
t.Errorf("Inconsistent name in info entry: %v", name)
}
}

View File

@@ -495,10 +495,11 @@ func transformSelect(sel *ir.SelectStmt) {
if ncase.Comm != nil {
n := ncase.Comm
oselrecv2 := func(dst, recv ir.Node, def bool) {
n := ir.NewAssignListStmt(n.Pos(), ir.OSELRECV2, []ir.Node{dst, ir.BlankNode}, []ir.Node{recv})
n.Def = def
n.SetTypecheck(1)
ncase.Comm = n
selrecv := ir.NewAssignListStmt(n.Pos(), ir.OSELRECV2, []ir.Node{dst, ir.BlankNode}, []ir.Node{recv})
selrecv.Def = def
selrecv.SetTypecheck(1)
selrecv.SetInit(n.Init())
ncase.Comm = selrecv
}
switch n.Op() {
case ir.OAS:

View File

@@ -952,6 +952,7 @@ func (x *expandState) storeArgOrLoad(pos src.XPos, b *Block, source, mem *Value,
return x.storeArgOrLoad(pos, b, source, mem, t, storeOffset, loadRegOffset, storeRc)
}
eltRO := x.regWidth(elt)
source.Type = t
for i := int64(0); i < t.NumElem(); i++ {
sel := source.Block.NewValue1I(pos, OpArraySelect, elt, i, source)
mem = x.storeArgOrLoad(pos, b, sel, mem, elt, storeOffset+i*elt.Width, loadRegOffset, storeRc.at(t, 0))
@@ -985,6 +986,7 @@ func (x *expandState) storeArgOrLoad(pos src.XPos, b *Block, source, mem *Value,
return x.storeArgOrLoad(pos, b, source, mem, t, storeOffset, loadRegOffset, storeRc)
}
source.Type = t
for i := 0; i < t.NumFields(); i++ {
fld := t.Field(i)
sel := source.Block.NewValue1I(pos, OpStructSelect, fld.Type, int64(i), source)

View File

@@ -78,7 +78,11 @@ func fuseBranchRedirect(f *Func) bool {
if v.Op != OpPhi {
continue
}
v.RemoveArg(k)
n := len(v.Args)
v.Args[k].Uses--
v.Args[k] = v.Args[n-1]
v.Args[n-1] = nil
v.Args = v.Args[:n-1]
phielimValue(v)
}
// Fix up child to have one more predecessor.

View File

@@ -497,9 +497,9 @@
(XOR x (MOVWconst [c])) => (XORconst [c] x)
(BIC x (MOVWconst [c])) => (BICconst [c] x)
(SLL x (MOVWconst [c])) => (SLLconst x [c&31]) // Note: I don't think we ever generate bad constant shifts (i.e. c>=32)
(SRL x (MOVWconst [c])) => (SRLconst x [c&31])
(SRA x (MOVWconst [c])) => (SRAconst x [c&31])
(SLL x (MOVWconst [c])) && 0 <= c && c < 32 => (SLLconst x [c])
(SRL x (MOVWconst [c])) && 0 <= c && c < 32 => (SRLconst x [c])
(SRA x (MOVWconst [c])) && 0 <= c && c < 32 => (SRAconst x [c])
(CMP x (MOVWconst [c])) => (CMPconst [c] x)
(CMP (MOVWconst [c]) x) => (InvertFlags (CMPconst [c] x))
@@ -1072,60 +1072,60 @@
(CMNshiftRL x (MOVWconst [c]) [d]) => (CMNconst x [int32(uint32(c)>>uint64(d))])
(CMNshiftRA x (MOVWconst [c]) [d]) => (CMNconst x [c>>uint64(d)])
(ADDshiftLLreg x y (MOVWconst [c])) => (ADDshiftLL x y [c])
(ADDshiftRLreg x y (MOVWconst [c])) => (ADDshiftRL x y [c])
(ADDshiftRAreg x y (MOVWconst [c])) => (ADDshiftRA x y [c])
(ADCshiftLLreg x y (MOVWconst [c]) flags) => (ADCshiftLL x y [c] flags)
(ADCshiftRLreg x y (MOVWconst [c]) flags) => (ADCshiftRL x y [c] flags)
(ADCshiftRAreg x y (MOVWconst [c]) flags) => (ADCshiftRA x y [c] flags)
(ADDSshiftLLreg x y (MOVWconst [c])) => (ADDSshiftLL x y [c])
(ADDSshiftRLreg x y (MOVWconst [c])) => (ADDSshiftRL x y [c])
(ADDSshiftRAreg x y (MOVWconst [c])) => (ADDSshiftRA x y [c])
(SUBshiftLLreg x y (MOVWconst [c])) => (SUBshiftLL x y [c])
(SUBshiftRLreg x y (MOVWconst [c])) => (SUBshiftRL x y [c])
(SUBshiftRAreg x y (MOVWconst [c])) => (SUBshiftRA x y [c])
(SBCshiftLLreg x y (MOVWconst [c]) flags) => (SBCshiftLL x y [c] flags)
(SBCshiftRLreg x y (MOVWconst [c]) flags) => (SBCshiftRL x y [c] flags)
(SBCshiftRAreg x y (MOVWconst [c]) flags) => (SBCshiftRA x y [c] flags)
(SUBSshiftLLreg x y (MOVWconst [c])) => (SUBSshiftLL x y [c])
(SUBSshiftRLreg x y (MOVWconst [c])) => (SUBSshiftRL x y [c])
(SUBSshiftRAreg x y (MOVWconst [c])) => (SUBSshiftRA x y [c])
(RSBshiftLLreg x y (MOVWconst [c])) => (RSBshiftLL x y [c])
(RSBshiftRLreg x y (MOVWconst [c])) => (RSBshiftRL x y [c])
(RSBshiftRAreg x y (MOVWconst [c])) => (RSBshiftRA x y [c])
(RSCshiftLLreg x y (MOVWconst [c]) flags) => (RSCshiftLL x y [c] flags)
(RSCshiftRLreg x y (MOVWconst [c]) flags) => (RSCshiftRL x y [c] flags)
(RSCshiftRAreg x y (MOVWconst [c]) flags) => (RSCshiftRA x y [c] flags)
(RSBSshiftLLreg x y (MOVWconst [c])) => (RSBSshiftLL x y [c])
(RSBSshiftRLreg x y (MOVWconst [c])) => (RSBSshiftRL x y [c])
(RSBSshiftRAreg x y (MOVWconst [c])) => (RSBSshiftRA x y [c])
(ANDshiftLLreg x y (MOVWconst [c])) => (ANDshiftLL x y [c])
(ANDshiftRLreg x y (MOVWconst [c])) => (ANDshiftRL x y [c])
(ANDshiftRAreg x y (MOVWconst [c])) => (ANDshiftRA x y [c])
(ORshiftLLreg x y (MOVWconst [c])) => (ORshiftLL x y [c])
(ORshiftRLreg x y (MOVWconst [c])) => (ORshiftRL x y [c])
(ORshiftRAreg x y (MOVWconst [c])) => (ORshiftRA x y [c])
(XORshiftLLreg x y (MOVWconst [c])) => (XORshiftLL x y [c])
(XORshiftRLreg x y (MOVWconst [c])) => (XORshiftRL x y [c])
(XORshiftRAreg x y (MOVWconst [c])) => (XORshiftRA x y [c])
(BICshiftLLreg x y (MOVWconst [c])) => (BICshiftLL x y [c])
(BICshiftRLreg x y (MOVWconst [c])) => (BICshiftRL x y [c])
(BICshiftRAreg x y (MOVWconst [c])) => (BICshiftRA x y [c])
(MVNshiftLLreg x (MOVWconst [c])) => (MVNshiftLL x [c])
(MVNshiftRLreg x (MOVWconst [c])) => (MVNshiftRL x [c])
(MVNshiftRAreg x (MOVWconst [c])) => (MVNshiftRA x [c])
(CMPshiftLLreg x y (MOVWconst [c])) => (CMPshiftLL x y [c])
(CMPshiftRLreg x y (MOVWconst [c])) => (CMPshiftRL x y [c])
(CMPshiftRAreg x y (MOVWconst [c])) => (CMPshiftRA x y [c])
(TSTshiftLLreg x y (MOVWconst [c])) => (TSTshiftLL x y [c])
(TSTshiftRLreg x y (MOVWconst [c])) => (TSTshiftRL x y [c])
(TSTshiftRAreg x y (MOVWconst [c])) => (TSTshiftRA x y [c])
(TEQshiftLLreg x y (MOVWconst [c])) => (TEQshiftLL x y [c])
(TEQshiftRLreg x y (MOVWconst [c])) => (TEQshiftRL x y [c])
(TEQshiftRAreg x y (MOVWconst [c])) => (TEQshiftRA x y [c])
(CMNshiftLLreg x y (MOVWconst [c])) => (CMNshiftLL x y [c])
(CMNshiftRLreg x y (MOVWconst [c])) => (CMNshiftRL x y [c])
(CMNshiftRAreg x y (MOVWconst [c])) => (CMNshiftRA x y [c])
(ADDshiftLLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (ADDshiftLL x y [c])
(ADDshiftRLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (ADDshiftRL x y [c])
(ADDshiftRAreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (ADDshiftRA x y [c])
(ADCshiftLLreg x y (MOVWconst [c]) flags) && 0 <= c && c < 32 => (ADCshiftLL x y [c] flags)
(ADCshiftRLreg x y (MOVWconst [c]) flags) && 0 <= c && c < 32 => (ADCshiftRL x y [c] flags)
(ADCshiftRAreg x y (MOVWconst [c]) flags) && 0 <= c && c < 32 => (ADCshiftRA x y [c] flags)
(ADDSshiftLLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (ADDSshiftLL x y [c])
(ADDSshiftRLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (ADDSshiftRL x y [c])
(ADDSshiftRAreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (ADDSshiftRA x y [c])
(SUBshiftLLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (SUBshiftLL x y [c])
(SUBshiftRLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (SUBshiftRL x y [c])
(SUBshiftRAreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (SUBshiftRA x y [c])
(SBCshiftLLreg x y (MOVWconst [c]) flags) && 0 <= c && c < 32 => (SBCshiftLL x y [c] flags)
(SBCshiftRLreg x y (MOVWconst [c]) flags) && 0 <= c && c < 32 => (SBCshiftRL x y [c] flags)
(SBCshiftRAreg x y (MOVWconst [c]) flags) && 0 <= c && c < 32 => (SBCshiftRA x y [c] flags)
(SUBSshiftLLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (SUBSshiftLL x y [c])
(SUBSshiftRLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (SUBSshiftRL x y [c])
(SUBSshiftRAreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (SUBSshiftRA x y [c])
(RSBshiftLLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (RSBshiftLL x y [c])
(RSBshiftRLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (RSBshiftRL x y [c])
(RSBshiftRAreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (RSBshiftRA x y [c])
(RSCshiftLLreg x y (MOVWconst [c]) flags) && 0 <= c && c < 32 => (RSCshiftLL x y [c] flags)
(RSCshiftRLreg x y (MOVWconst [c]) flags) && 0 <= c && c < 32 => (RSCshiftRL x y [c] flags)
(RSCshiftRAreg x y (MOVWconst [c]) flags) && 0 <= c && c < 32 => (RSCshiftRA x y [c] flags)
(RSBSshiftLLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (RSBSshiftLL x y [c])
(RSBSshiftRLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (RSBSshiftRL x y [c])
(RSBSshiftRAreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (RSBSshiftRA x y [c])
(ANDshiftLLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (ANDshiftLL x y [c])
(ANDshiftRLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (ANDshiftRL x y [c])
(ANDshiftRAreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (ANDshiftRA x y [c])
(ORshiftLLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (ORshiftLL x y [c])
(ORshiftRLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (ORshiftRL x y [c])
(ORshiftRAreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (ORshiftRA x y [c])
(XORshiftLLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (XORshiftLL x y [c])
(XORshiftRLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (XORshiftRL x y [c])
(XORshiftRAreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (XORshiftRA x y [c])
(BICshiftLLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (BICshiftLL x y [c])
(BICshiftRLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (BICshiftRL x y [c])
(BICshiftRAreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (BICshiftRA x y [c])
(MVNshiftLLreg x (MOVWconst [c])) && 0 <= c && c < 32 => (MVNshiftLL x [c])
(MVNshiftRLreg x (MOVWconst [c])) && 0 <= c && c < 32 => (MVNshiftRL x [c])
(MVNshiftRAreg x (MOVWconst [c])) && 0 <= c && c < 32 => (MVNshiftRA x [c])
(CMPshiftLLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (CMPshiftLL x y [c])
(CMPshiftRLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (CMPshiftRL x y [c])
(CMPshiftRAreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (CMPshiftRA x y [c])
(TSTshiftLLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (TSTshiftLL x y [c])
(TSTshiftRLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (TSTshiftRL x y [c])
(TSTshiftRAreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (TSTshiftRA x y [c])
(TEQshiftLLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (TEQshiftLL x y [c])
(TEQshiftRLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (TEQshiftRL x y [c])
(TEQshiftRAreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (TEQshiftRA x y [c])
(CMNshiftLLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (CMNshiftLL x y [c])
(CMNshiftRLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (CMNshiftRL x y [c])
(CMNshiftRAreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (CMNshiftRA x y [c])
// Generate rotates
(ADDshiftLL [c] (SRLconst x [32-c]) x) => (SRRconst [32-c] x)
@@ -1237,24 +1237,24 @@
(AND x (MVN y)) => (BIC x y)
// simplification with *shift ops
(SUBshiftLL x (SLLconst x [c]) [d]) && c==d => (MOVWconst [0])
(SUBshiftRL x (SRLconst x [c]) [d]) && c==d => (MOVWconst [0])
(SUBshiftRA x (SRAconst x [c]) [d]) && c==d => (MOVWconst [0])
(RSBshiftLL x (SLLconst x [c]) [d]) && c==d => (MOVWconst [0])
(RSBshiftRL x (SRLconst x [c]) [d]) && c==d => (MOVWconst [0])
(RSBshiftRA x (SRAconst x [c]) [d]) && c==d => (MOVWconst [0])
(ANDshiftLL x y:(SLLconst x [c]) [d]) && c==d => y
(ANDshiftRL x y:(SRLconst x [c]) [d]) && c==d => y
(ANDshiftRA x y:(SRAconst x [c]) [d]) && c==d => y
(ORshiftLL x y:(SLLconst x [c]) [d]) && c==d => y
(ORshiftRL x y:(SRLconst x [c]) [d]) && c==d => y
(ORshiftRA x y:(SRAconst x [c]) [d]) && c==d => y
(XORshiftLL x (SLLconst x [c]) [d]) && c==d => (MOVWconst [0])
(XORshiftRL x (SRLconst x [c]) [d]) && c==d => (MOVWconst [0])
(XORshiftRA x (SRAconst x [c]) [d]) && c==d => (MOVWconst [0])
(BICshiftLL x (SLLconst x [c]) [d]) && c==d => (MOVWconst [0])
(BICshiftRL x (SRLconst x [c]) [d]) && c==d => (MOVWconst [0])
(BICshiftRA x (SRAconst x [c]) [d]) && c==d => (MOVWconst [0])
(SUBshiftLL (SLLconst x [c]) x [c]) => (MOVWconst [0])
(SUBshiftRL (SRLconst x [c]) x [c]) => (MOVWconst [0])
(SUBshiftRA (SRAconst x [c]) x [c]) => (MOVWconst [0])
(RSBshiftLL (SLLconst x [c]) x [c]) => (MOVWconst [0])
(RSBshiftRL (SRLconst x [c]) x [c]) => (MOVWconst [0])
(RSBshiftRA (SRAconst x [c]) x [c]) => (MOVWconst [0])
(ANDshiftLL y:(SLLconst x [c]) x [c]) => y
(ANDshiftRL y:(SRLconst x [c]) x [c]) => y
(ANDshiftRA y:(SRAconst x [c]) x [c]) => y
(ORshiftLL y:(SLLconst x [c]) x [c]) => y
(ORshiftRL y:(SRLconst x [c]) x [c]) => y
(ORshiftRA y:(SRAconst x [c]) x [c]) => y
(XORshiftLL (SLLconst x [c]) x [c]) => (MOVWconst [0])
(XORshiftRL (SRLconst x [c]) x [c]) => (MOVWconst [0])
(XORshiftRA (SRAconst x [c]) x [c]) => (MOVWconst [0])
(BICshiftLL (SLLconst x [c]) x [c]) => (MOVWconst [0])
(BICshiftRL (SRLconst x [c]) x [c]) => (MOVWconst [0])
(BICshiftRA (SRAconst x [c]) x [c]) => (MOVWconst [0])
(AND x (MVNshiftLL y [c])) => (BICshiftLL x y [c])
(AND x (MVNshiftRL y [c])) => (BICshiftRL x y [c])
(AND x (MVNshiftRA y [c])) => (BICshiftRA x y [c])

View File

@@ -1698,27 +1698,27 @@
(TSTshiftRA x (MOVDconst [c]) [d]) => (TSTconst x [c>>uint64(d)])
// simplification with *shift ops
(SUBshiftLL x (SLLconst x [c]) [d]) && c==d => (MOVDconst [0])
(SUBshiftRL x (SRLconst x [c]) [d]) && c==d => (MOVDconst [0])
(SUBshiftRA x (SRAconst x [c]) [d]) && c==d => (MOVDconst [0])
(ANDshiftLL x y:(SLLconst x [c]) [d]) && c==d => y
(ANDshiftRL x y:(SRLconst x [c]) [d]) && c==d => y
(ANDshiftRA x y:(SRAconst x [c]) [d]) && c==d => y
(ORshiftLL x y:(SLLconst x [c]) [d]) && c==d => y
(ORshiftRL x y:(SRLconst x [c]) [d]) && c==d => y
(ORshiftRA x y:(SRAconst x [c]) [d]) && c==d => y
(XORshiftLL x (SLLconst x [c]) [d]) && c==d => (MOVDconst [0])
(XORshiftRL x (SRLconst x [c]) [d]) && c==d => (MOVDconst [0])
(XORshiftRA x (SRAconst x [c]) [d]) && c==d => (MOVDconst [0])
(BICshiftLL x (SLLconst x [c]) [d]) && c==d => (MOVDconst [0])
(BICshiftRL x (SRLconst x [c]) [d]) && c==d => (MOVDconst [0])
(BICshiftRA x (SRAconst x [c]) [d]) && c==d => (MOVDconst [0])
(EONshiftLL x (SLLconst x [c]) [d]) && c==d => (MOVDconst [-1])
(EONshiftRL x (SRLconst x [c]) [d]) && c==d => (MOVDconst [-1])
(EONshiftRA x (SRAconst x [c]) [d]) && c==d => (MOVDconst [-1])
(ORNshiftLL x (SLLconst x [c]) [d]) && c==d => (MOVDconst [-1])
(ORNshiftRL x (SRLconst x [c]) [d]) && c==d => (MOVDconst [-1])
(ORNshiftRA x (SRAconst x [c]) [d]) && c==d => (MOVDconst [-1])
(SUBshiftLL (SLLconst x [c]) x [c]) => (MOVDconst [0])
(SUBshiftRL (SRLconst x [c]) x [c]) => (MOVDconst [0])
(SUBshiftRA (SRAconst x [c]) x [c]) => (MOVDconst [0])
(ANDshiftLL y:(SLLconst x [c]) x [c]) => y
(ANDshiftRL y:(SRLconst x [c]) x [c]) => y
(ANDshiftRA y:(SRAconst x [c]) x [c]) => y
(ORshiftLL y:(SLLconst x [c]) x [c]) => y
(ORshiftRL y:(SRLconst x [c]) x [c]) => y
(ORshiftRA y:(SRAconst x [c]) x [c]) => y
(XORshiftLL (SLLconst x [c]) x [c]) => (MOVDconst [0])
(XORshiftRL (SRLconst x [c]) x [c]) => (MOVDconst [0])
(XORshiftRA (SRAconst x [c]) x [c]) => (MOVDconst [0])
(BICshiftLL (SLLconst x [c]) x [c]) => (MOVDconst [0])
(BICshiftRL (SRLconst x [c]) x [c]) => (MOVDconst [0])
(BICshiftRA (SRAconst x [c]) x [c]) => (MOVDconst [0])
(EONshiftLL (SLLconst x [c]) x [c]) => (MOVDconst [-1])
(EONshiftRL (SRLconst x [c]) x [c]) => (MOVDconst [-1])
(EONshiftRA (SRAconst x [c]) x [c]) => (MOVDconst [-1])
(ORNshiftLL (SLLconst x [c]) x [c]) => (MOVDconst [-1])
(ORNshiftRL (SRLconst x [c]) x [c]) => (MOVDconst [-1])
(ORNshiftRA (SRAconst x [c]) x [c]) => (MOVDconst [-1])
// Generate rotates with const shift
(ADDshiftLL [c] (SRLconst x [64-c]) x) => (RORconst [64-c] x)

View File

@@ -228,14 +228,15 @@ func init() {
// shifts
{name: "SLL", argLength: 2, reg: gp21, asm: "SLL"}, // arg0 << arg1, shift amount is mod 256
{name: "SLLconst", argLength: 1, reg: gp11, asm: "SLL", aux: "Int32"}, // arg0 << auxInt
{name: "SLLconst", argLength: 1, reg: gp11, asm: "SLL", aux: "Int32"}, // arg0 << auxInt, 0 <= auxInt < 32
{name: "SRL", argLength: 2, reg: gp21, asm: "SRL"}, // arg0 >> arg1, unsigned, shift amount is mod 256
{name: "SRLconst", argLength: 1, reg: gp11, asm: "SRL", aux: "Int32"}, // arg0 >> auxInt, unsigned
{name: "SRLconst", argLength: 1, reg: gp11, asm: "SRL", aux: "Int32"}, // arg0 >> auxInt, unsigned, 0 <= auxInt < 32
{name: "SRA", argLength: 2, reg: gp21, asm: "SRA"}, // arg0 >> arg1, signed, shift amount is mod 256
{name: "SRAconst", argLength: 1, reg: gp11, asm: "SRA", aux: "Int32"}, // arg0 >> auxInt, signed
{name: "SRAconst", argLength: 1, reg: gp11, asm: "SRA", aux: "Int32"}, // arg0 >> auxInt, signed, 0 <= auxInt < 32
{name: "SRR", argLength: 2, reg: gp21}, // arg0 right rotate by arg1 bits
{name: "SRRconst", argLength: 1, reg: gp11, aux: "Int32"}, // arg0 right rotate by auxInt bits
{name: "SRRconst", argLength: 1, reg: gp11, aux: "Int32"}, // arg0 right rotate by auxInt bits, 0 <= auxInt < 32
// auxInt for all of these satisfy 0 <= auxInt < 32
{name: "ADDshiftLL", argLength: 2, reg: gp21, asm: "ADD", aux: "Int32"}, // arg0 + arg1<<auxInt
{name: "ADDshiftRL", argLength: 2, reg: gp21, asm: "ADD", aux: "Int32"}, // arg0 + arg1>>auxInt, unsigned shift
{name: "ADDshiftRA", argLength: 2, reg: gp21, asm: "ADD", aux: "Int32"}, // arg0 + arg1>>auxInt, signed shift

View File

@@ -106,7 +106,7 @@ var genericOps = []opData{
// For shifts, AxB means the shifted value has A bits and the shift amount has B bits.
// Shift amounts are considered unsigned.
// If arg1 is known to be less than the number of bits in arg0,
// If arg1 is known to be nonnegative and less than the number of bits in arg0,
// then auxInt may be set to 1.
// This enables better code generation on some platforms.
{name: "Lsh8x8", argLength: 2, aux: "Bool"}, // arg0 << arg1

File diff suppressed because it is too large Load Diff

View File

@@ -2265,18 +2265,16 @@ func rewriteValueARM64_OpARM64ANDshiftLL(v *Value) bool {
v.AddArg(x)
return true
}
// match: (ANDshiftLL x y:(SLLconst x [c]) [d])
// cond: c==d
// match: (ANDshiftLL y:(SLLconst x [c]) x [c])
// result: y
for {
d := auxIntToInt64(v.AuxInt)
x := v_0
y := v_1
if y.Op != OpARM64SLLconst {
c := auxIntToInt64(v.AuxInt)
y := v_0
if y.Op != OpARM64SLLconst || auxIntToInt64(y.AuxInt) != c {
break
}
c := auxIntToInt64(y.AuxInt)
if x != y.Args[0] || !(c == d) {
x := y.Args[0]
if x != v_1 {
break
}
v.copyOf(y)
@@ -2319,18 +2317,16 @@ func rewriteValueARM64_OpARM64ANDshiftRA(v *Value) bool {
v.AddArg(x)
return true
}
// match: (ANDshiftRA x y:(SRAconst x [c]) [d])
// cond: c==d
// match: (ANDshiftRA y:(SRAconst x [c]) x [c])
// result: y
for {
d := auxIntToInt64(v.AuxInt)
x := v_0
y := v_1
if y.Op != OpARM64SRAconst {
c := auxIntToInt64(v.AuxInt)
y := v_0
if y.Op != OpARM64SRAconst || auxIntToInt64(y.AuxInt) != c {
break
}
c := auxIntToInt64(y.AuxInt)
if x != y.Args[0] || !(c == d) {
x := y.Args[0]
if x != v_1 {
break
}
v.copyOf(y)
@@ -2373,18 +2369,16 @@ func rewriteValueARM64_OpARM64ANDshiftRL(v *Value) bool {
v.AddArg(x)
return true
}
// match: (ANDshiftRL x y:(SRLconst x [c]) [d])
// cond: c==d
// match: (ANDshiftRL y:(SRLconst x [c]) x [c])
// result: y
for {
d := auxIntToInt64(v.AuxInt)
x := v_0
y := v_1
if y.Op != OpARM64SRLconst {
c := auxIntToInt64(v.AuxInt)
y := v_0
if y.Op != OpARM64SRLconst || auxIntToInt64(y.AuxInt) != c {
break
}
c := auxIntToInt64(y.AuxInt)
if x != y.Args[0] || !(c == d) {
x := y.Args[0]
if x != v_1 {
break
}
v.copyOf(y)
@@ -2495,17 +2489,15 @@ func rewriteValueARM64_OpARM64BICshiftLL(v *Value) bool {
v.AddArg(x)
return true
}
// match: (BICshiftLL x (SLLconst x [c]) [d])
// cond: c==d
// match: (BICshiftLL (SLLconst x [c]) x [c])
// result: (MOVDconst [0])
for {
d := auxIntToInt64(v.AuxInt)
x := v_0
if v_1.Op != OpARM64SLLconst {
c := auxIntToInt64(v.AuxInt)
if v_0.Op != OpARM64SLLconst || auxIntToInt64(v_0.AuxInt) != c {
break
}
c := auxIntToInt64(v_1.AuxInt)
if x != v_1.Args[0] || !(c == d) {
x := v_0.Args[0]
if x != v_1 {
break
}
v.reset(OpARM64MOVDconst)
@@ -2531,17 +2523,15 @@ func rewriteValueARM64_OpARM64BICshiftRA(v *Value) bool {
v.AddArg(x)
return true
}
// match: (BICshiftRA x (SRAconst x [c]) [d])
// cond: c==d
// match: (BICshiftRA (SRAconst x [c]) x [c])
// result: (MOVDconst [0])
for {
d := auxIntToInt64(v.AuxInt)
x := v_0
if v_1.Op != OpARM64SRAconst {
c := auxIntToInt64(v.AuxInt)
if v_0.Op != OpARM64SRAconst || auxIntToInt64(v_0.AuxInt) != c {
break
}
c := auxIntToInt64(v_1.AuxInt)
if x != v_1.Args[0] || !(c == d) {
x := v_0.Args[0]
if x != v_1 {
break
}
v.reset(OpARM64MOVDconst)
@@ -2567,17 +2557,15 @@ func rewriteValueARM64_OpARM64BICshiftRL(v *Value) bool {
v.AddArg(x)
return true
}
// match: (BICshiftRL x (SRLconst x [c]) [d])
// cond: c==d
// match: (BICshiftRL (SRLconst x [c]) x [c])
// result: (MOVDconst [0])
for {
d := auxIntToInt64(v.AuxInt)
x := v_0
if v_1.Op != OpARM64SRLconst {
c := auxIntToInt64(v.AuxInt)
if v_0.Op != OpARM64SRLconst || auxIntToInt64(v_0.AuxInt) != c {
break
}
c := auxIntToInt64(v_1.AuxInt)
if x != v_1.Args[0] || !(c == d) {
x := v_0.Args[0]
if x != v_1 {
break
}
v.reset(OpARM64MOVDconst)
@@ -3945,17 +3933,15 @@ func rewriteValueARM64_OpARM64EONshiftLL(v *Value) bool {
v.AddArg(x)
return true
}
// match: (EONshiftLL x (SLLconst x [c]) [d])
// cond: c==d
// match: (EONshiftLL (SLLconst x [c]) x [c])
// result: (MOVDconst [-1])
for {
d := auxIntToInt64(v.AuxInt)
x := v_0
if v_1.Op != OpARM64SLLconst {
c := auxIntToInt64(v.AuxInt)
if v_0.Op != OpARM64SLLconst || auxIntToInt64(v_0.AuxInt) != c {
break
}
c := auxIntToInt64(v_1.AuxInt)
if x != v_1.Args[0] || !(c == d) {
x := v_0.Args[0]
if x != v_1 {
break
}
v.reset(OpARM64MOVDconst)
@@ -3981,17 +3967,15 @@ func rewriteValueARM64_OpARM64EONshiftRA(v *Value) bool {
v.AddArg(x)
return true
}
// match: (EONshiftRA x (SRAconst x [c]) [d])
// cond: c==d
// match: (EONshiftRA (SRAconst x [c]) x [c])
// result: (MOVDconst [-1])
for {
d := auxIntToInt64(v.AuxInt)
x := v_0
if v_1.Op != OpARM64SRAconst {
c := auxIntToInt64(v.AuxInt)
if v_0.Op != OpARM64SRAconst || auxIntToInt64(v_0.AuxInt) != c {
break
}
c := auxIntToInt64(v_1.AuxInt)
if x != v_1.Args[0] || !(c == d) {
x := v_0.Args[0]
if x != v_1 {
break
}
v.reset(OpARM64MOVDconst)
@@ -4017,17 +4001,15 @@ func rewriteValueARM64_OpARM64EONshiftRL(v *Value) bool {
v.AddArg(x)
return true
}
// match: (EONshiftRL x (SRLconst x [c]) [d])
// cond: c==d
// match: (EONshiftRL (SRLconst x [c]) x [c])
// result: (MOVDconst [-1])
for {
d := auxIntToInt64(v.AuxInt)
x := v_0
if v_1.Op != OpARM64SRLconst {
c := auxIntToInt64(v.AuxInt)
if v_0.Op != OpARM64SRLconst || auxIntToInt64(v_0.AuxInt) != c {
break
}
c := auxIntToInt64(v_1.AuxInt)
if x != v_1.Args[0] || !(c == d) {
x := v_0.Args[0]
if x != v_1 {
break
}
v.reset(OpARM64MOVDconst)
@@ -17819,17 +17801,15 @@ func rewriteValueARM64_OpARM64ORNshiftLL(v *Value) bool {
v.AddArg(x)
return true
}
// match: (ORNshiftLL x (SLLconst x [c]) [d])
// cond: c==d
// match: (ORNshiftLL (SLLconst x [c]) x [c])
// result: (MOVDconst [-1])
for {
d := auxIntToInt64(v.AuxInt)
x := v_0
if v_1.Op != OpARM64SLLconst {
c := auxIntToInt64(v.AuxInt)
if v_0.Op != OpARM64SLLconst || auxIntToInt64(v_0.AuxInt) != c {
break
}
c := auxIntToInt64(v_1.AuxInt)
if x != v_1.Args[0] || !(c == d) {
x := v_0.Args[0]
if x != v_1 {
break
}
v.reset(OpARM64MOVDconst)
@@ -17855,17 +17835,15 @@ func rewriteValueARM64_OpARM64ORNshiftRA(v *Value) bool {
v.AddArg(x)
return true
}
// match: (ORNshiftRA x (SRAconst x [c]) [d])
// cond: c==d
// match: (ORNshiftRA (SRAconst x [c]) x [c])
// result: (MOVDconst [-1])
for {
d := auxIntToInt64(v.AuxInt)
x := v_0
if v_1.Op != OpARM64SRAconst {
c := auxIntToInt64(v.AuxInt)
if v_0.Op != OpARM64SRAconst || auxIntToInt64(v_0.AuxInt) != c {
break
}
c := auxIntToInt64(v_1.AuxInt)
if x != v_1.Args[0] || !(c == d) {
x := v_0.Args[0]
if x != v_1 {
break
}
v.reset(OpARM64MOVDconst)
@@ -17891,17 +17869,15 @@ func rewriteValueARM64_OpARM64ORNshiftRL(v *Value) bool {
v.AddArg(x)
return true
}
// match: (ORNshiftRL x (SRLconst x [c]) [d])
// cond: c==d
// match: (ORNshiftRL (SRLconst x [c]) x [c])
// result: (MOVDconst [-1])
for {
d := auxIntToInt64(v.AuxInt)
x := v_0
if v_1.Op != OpARM64SRLconst {
c := auxIntToInt64(v.AuxInt)
if v_0.Op != OpARM64SRLconst || auxIntToInt64(v_0.AuxInt) != c {
break
}
c := auxIntToInt64(v_1.AuxInt)
if x != v_1.Args[0] || !(c == d) {
x := v_0.Args[0]
if x != v_1 {
break
}
v.reset(OpARM64MOVDconst)
@@ -18014,18 +17990,16 @@ func rewriteValueARM64_OpARM64ORshiftLL(v *Value) bool {
v.AddArg(x)
return true
}
// match: (ORshiftLL x y:(SLLconst x [c]) [d])
// cond: c==d
// match: (ORshiftLL y:(SLLconst x [c]) x [c])
// result: y
for {
d := auxIntToInt64(v.AuxInt)
x := v_0
y := v_1
if y.Op != OpARM64SLLconst {
c := auxIntToInt64(v.AuxInt)
y := v_0
if y.Op != OpARM64SLLconst || auxIntToInt64(y.AuxInt) != c {
break
}
c := auxIntToInt64(y.AuxInt)
if x != y.Args[0] || !(c == d) {
x := y.Args[0]
if x != v_1 {
break
}
v.copyOf(y)
@@ -19694,18 +19668,16 @@ func rewriteValueARM64_OpARM64ORshiftRA(v *Value) bool {
v.AddArg(x)
return true
}
// match: (ORshiftRA x y:(SRAconst x [c]) [d])
// cond: c==d
// match: (ORshiftRA y:(SRAconst x [c]) x [c])
// result: y
for {
d := auxIntToInt64(v.AuxInt)
x := v_0
y := v_1
if y.Op != OpARM64SRAconst {
c := auxIntToInt64(v.AuxInt)
y := v_0
if y.Op != OpARM64SRAconst || auxIntToInt64(y.AuxInt) != c {
break
}
c := auxIntToInt64(y.AuxInt)
if x != y.Args[0] || !(c == d) {
x := y.Args[0]
if x != v_1 {
break
}
v.copyOf(y)
@@ -19748,18 +19720,16 @@ func rewriteValueARM64_OpARM64ORshiftRL(v *Value) bool {
v.AddArg(x)
return true
}
// match: (ORshiftRL x y:(SRLconst x [c]) [d])
// cond: c==d
// match: (ORshiftRL y:(SRLconst x [c]) x [c])
// result: y
for {
d := auxIntToInt64(v.AuxInt)
x := v_0
y := v_1
if y.Op != OpARM64SRLconst {
c := auxIntToInt64(v.AuxInt)
y := v_0
if y.Op != OpARM64SRLconst || auxIntToInt64(y.AuxInt) != c {
break
}
c := auxIntToInt64(y.AuxInt)
if x != y.Args[0] || !(c == d) {
x := y.Args[0]
if x != v_1 {
break
}
v.copyOf(y)
@@ -20836,17 +20806,15 @@ func rewriteValueARM64_OpARM64SUBshiftLL(v *Value) bool {
v.AddArg(x)
return true
}
// match: (SUBshiftLL x (SLLconst x [c]) [d])
// cond: c==d
// match: (SUBshiftLL (SLLconst x [c]) x [c])
// result: (MOVDconst [0])
for {
d := auxIntToInt64(v.AuxInt)
x := v_0
if v_1.Op != OpARM64SLLconst {
c := auxIntToInt64(v.AuxInt)
if v_0.Op != OpARM64SLLconst || auxIntToInt64(v_0.AuxInt) != c {
break
}
c := auxIntToInt64(v_1.AuxInt)
if x != v_1.Args[0] || !(c == d) {
x := v_0.Args[0]
if x != v_1 {
break
}
v.reset(OpARM64MOVDconst)
@@ -20872,17 +20840,15 @@ func rewriteValueARM64_OpARM64SUBshiftRA(v *Value) bool {
v.AddArg(x)
return true
}
// match: (SUBshiftRA x (SRAconst x [c]) [d])
// cond: c==d
// match: (SUBshiftRA (SRAconst x [c]) x [c])
// result: (MOVDconst [0])
for {
d := auxIntToInt64(v.AuxInt)
x := v_0
if v_1.Op != OpARM64SRAconst {
c := auxIntToInt64(v.AuxInt)
if v_0.Op != OpARM64SRAconst || auxIntToInt64(v_0.AuxInt) != c {
break
}
c := auxIntToInt64(v_1.AuxInt)
if x != v_1.Args[0] || !(c == d) {
x := v_0.Args[0]
if x != v_1 {
break
}
v.reset(OpARM64MOVDconst)
@@ -20908,17 +20874,15 @@ func rewriteValueARM64_OpARM64SUBshiftRL(v *Value) bool {
v.AddArg(x)
return true
}
// match: (SUBshiftRL x (SRLconst x [c]) [d])
// cond: c==d
// match: (SUBshiftRL (SRLconst x [c]) x [c])
// result: (MOVDconst [0])
for {
d := auxIntToInt64(v.AuxInt)
x := v_0
if v_1.Op != OpARM64SRLconst {
c := auxIntToInt64(v.AuxInt)
if v_0.Op != OpARM64SRLconst || auxIntToInt64(v_0.AuxInt) != c {
break
}
c := auxIntToInt64(v_1.AuxInt)
if x != v_1.Args[0] || !(c == d) {
x := v_0.Args[0]
if x != v_1 {
break
}
v.reset(OpARM64MOVDconst)
@@ -22007,17 +21971,15 @@ func rewriteValueARM64_OpARM64XORshiftLL(v *Value) bool {
v.AddArg(x)
return true
}
// match: (XORshiftLL x (SLLconst x [c]) [d])
// cond: c==d
// match: (XORshiftLL (SLLconst x [c]) x [c])
// result: (MOVDconst [0])
for {
d := auxIntToInt64(v.AuxInt)
x := v_0
if v_1.Op != OpARM64SLLconst {
c := auxIntToInt64(v.AuxInt)
if v_0.Op != OpARM64SLLconst || auxIntToInt64(v_0.AuxInt) != c {
break
}
c := auxIntToInt64(v_1.AuxInt)
if x != v_1.Args[0] || !(c == d) {
x := v_0.Args[0]
if x != v_1 {
break
}
v.reset(OpARM64MOVDconst)
@@ -22219,17 +22181,15 @@ func rewriteValueARM64_OpARM64XORshiftRA(v *Value) bool {
v.AddArg(x)
return true
}
// match: (XORshiftRA x (SRAconst x [c]) [d])
// cond: c==d
// match: (XORshiftRA (SRAconst x [c]) x [c])
// result: (MOVDconst [0])
for {
d := auxIntToInt64(v.AuxInt)
x := v_0
if v_1.Op != OpARM64SRAconst {
c := auxIntToInt64(v.AuxInt)
if v_0.Op != OpARM64SRAconst || auxIntToInt64(v_0.AuxInt) != c {
break
}
c := auxIntToInt64(v_1.AuxInt)
if x != v_1.Args[0] || !(c == d) {
x := v_0.Args[0]
if x != v_1 {
break
}
v.reset(OpARM64MOVDconst)
@@ -22273,17 +22233,15 @@ func rewriteValueARM64_OpARM64XORshiftRL(v *Value) bool {
v.AddArg(x)
return true
}
// match: (XORshiftRL x (SRLconst x [c]) [d])
// cond: c==d
// match: (XORshiftRL (SRLconst x [c]) x [c])
// result: (MOVDconst [0])
for {
d := auxIntToInt64(v.AuxInt)
x := v_0
if v_1.Op != OpARM64SRLconst {
c := auxIntToInt64(v.AuxInt)
if v_0.Op != OpARM64SRLconst || auxIntToInt64(v_0.AuxInt) != c {
break
}
c := auxIntToInt64(v_1.AuxInt)
if x != v_1.Args[0] || !(c == d) {
x := v_0.Args[0]
if x != v_1 {
break
}
v.reset(OpARM64MOVDconst)

View File

@@ -2387,6 +2387,175 @@ func (s *state) ssaShiftOp(op ir.Op, t *types.Type, u *types.Type) ssa.Op {
return x
}
func (s *state) conv(n ir.Node, v *ssa.Value, ft, tt *types.Type) *ssa.Value {
if ft.IsBoolean() && tt.IsKind(types.TUINT8) {
// Bool -> uint8 is generated internally when indexing into runtime.staticbyte.
return s.newValue1(ssa.OpCopy, tt, v)
}
if ft.IsInteger() && tt.IsInteger() {
var op ssa.Op
if tt.Size() == ft.Size() {
op = ssa.OpCopy
} else if tt.Size() < ft.Size() {
// truncation
switch 10*ft.Size() + tt.Size() {
case 21:
op = ssa.OpTrunc16to8
case 41:
op = ssa.OpTrunc32to8
case 42:
op = ssa.OpTrunc32to16
case 81:
op = ssa.OpTrunc64to8
case 82:
op = ssa.OpTrunc64to16
case 84:
op = ssa.OpTrunc64to32
default:
s.Fatalf("weird integer truncation %v -> %v", ft, tt)
}
} else if ft.IsSigned() {
// sign extension
switch 10*ft.Size() + tt.Size() {
case 12:
op = ssa.OpSignExt8to16
case 14:
op = ssa.OpSignExt8to32
case 18:
op = ssa.OpSignExt8to64
case 24:
op = ssa.OpSignExt16to32
case 28:
op = ssa.OpSignExt16to64
case 48:
op = ssa.OpSignExt32to64
default:
s.Fatalf("bad integer sign extension %v -> %v", ft, tt)
}
} else {
// zero extension
switch 10*ft.Size() + tt.Size() {
case 12:
op = ssa.OpZeroExt8to16
case 14:
op = ssa.OpZeroExt8to32
case 18:
op = ssa.OpZeroExt8to64
case 24:
op = ssa.OpZeroExt16to32
case 28:
op = ssa.OpZeroExt16to64
case 48:
op = ssa.OpZeroExt32to64
default:
s.Fatalf("weird integer sign extension %v -> %v", ft, tt)
}
}
return s.newValue1(op, tt, v)
}
if ft.IsFloat() || tt.IsFloat() {
conv, ok := fpConvOpToSSA[twoTypes{s.concreteEtype(ft), s.concreteEtype(tt)}]
if s.config.RegSize == 4 && Arch.LinkArch.Family != sys.MIPS && !s.softFloat {
if conv1, ok1 := fpConvOpToSSA32[twoTypes{s.concreteEtype(ft), s.concreteEtype(tt)}]; ok1 {
conv = conv1
}
}
if Arch.LinkArch.Family == sys.ARM64 || Arch.LinkArch.Family == sys.Wasm || Arch.LinkArch.Family == sys.S390X || s.softFloat {
if conv1, ok1 := uint64fpConvOpToSSA[twoTypes{s.concreteEtype(ft), s.concreteEtype(tt)}]; ok1 {
conv = conv1
}
}
if Arch.LinkArch.Family == sys.MIPS && !s.softFloat {
if ft.Size() == 4 && ft.IsInteger() && !ft.IsSigned() {
// tt is float32 or float64, and ft is also unsigned
if tt.Size() == 4 {
return s.uint32Tofloat32(n, v, ft, tt)
}
if tt.Size() == 8 {
return s.uint32Tofloat64(n, v, ft, tt)
}
} else if tt.Size() == 4 && tt.IsInteger() && !tt.IsSigned() {
// ft is float32 or float64, and tt is unsigned integer
if ft.Size() == 4 {
return s.float32ToUint32(n, v, ft, tt)
}
if ft.Size() == 8 {
return s.float64ToUint32(n, v, ft, tt)
}
}
}
if !ok {
s.Fatalf("weird float conversion %v -> %v", ft, tt)
}
op1, op2, it := conv.op1, conv.op2, conv.intermediateType
if op1 != ssa.OpInvalid && op2 != ssa.OpInvalid {
// normal case, not tripping over unsigned 64
if op1 == ssa.OpCopy {
if op2 == ssa.OpCopy {
return v
}
return s.newValueOrSfCall1(op2, tt, v)
}
if op2 == ssa.OpCopy {
return s.newValueOrSfCall1(op1, tt, v)
}
return s.newValueOrSfCall1(op2, tt, s.newValueOrSfCall1(op1, types.Types[it], v))
}
// Tricky 64-bit unsigned cases.
if ft.IsInteger() {
// tt is float32 or float64, and ft is also unsigned
if tt.Size() == 4 {
return s.uint64Tofloat32(n, v, ft, tt)
}
if tt.Size() == 8 {
return s.uint64Tofloat64(n, v, ft, tt)
}
s.Fatalf("weird unsigned integer to float conversion %v -> %v", ft, tt)
}
// ft is float32 or float64, and tt is unsigned integer
if ft.Size() == 4 {
return s.float32ToUint64(n, v, ft, tt)
}
if ft.Size() == 8 {
return s.float64ToUint64(n, v, ft, tt)
}
s.Fatalf("weird float to unsigned integer conversion %v -> %v", ft, tt)
return nil
}
if ft.IsComplex() && tt.IsComplex() {
var op ssa.Op
if ft.Size() == tt.Size() {
switch ft.Size() {
case 8:
op = ssa.OpRound32F
case 16:
op = ssa.OpRound64F
default:
s.Fatalf("weird complex conversion %v -> %v", ft, tt)
}
} else if ft.Size() == 8 && tt.Size() == 16 {
op = ssa.OpCvt32Fto64F
} else if ft.Size() == 16 && tt.Size() == 8 {
op = ssa.OpCvt64Fto32F
} else {
s.Fatalf("weird complex conversion %v -> %v", ft, tt)
}
ftp := types.FloatForComplex(ft)
ttp := types.FloatForComplex(tt)
return s.newValue2(ssa.OpComplexMake, tt,
s.newValueOrSfCall1(op, ttp, s.newValue1(ssa.OpComplexReal, ftp, v)),
s.newValueOrSfCall1(op, ttp, s.newValue1(ssa.OpComplexImag, ftp, v)))
}
s.Fatalf("unhandled OCONV %s -> %s", ft.Kind(), tt.Kind())
return nil
}
// expr converts the expression n to ssa, adds it to s and returns the ssa result.
func (s *state) expr(n ir.Node) *ssa.Value {
if ir.HasUniquePos(n) {
@@ -2574,174 +2743,7 @@ func (s *state) expr(n ir.Node) *ssa.Value {
case ir.OCONV:
n := n.(*ir.ConvExpr)
x := s.expr(n.X)
ft := n.X.Type() // from type
tt := n.Type() // to type
if ft.IsBoolean() && tt.IsKind(types.TUINT8) {
// Bool -> uint8 is generated internally when indexing into runtime.staticbyte.
return s.newValue1(ssa.OpCopy, n.Type(), x)
}
if ft.IsInteger() && tt.IsInteger() {
var op ssa.Op
if tt.Size() == ft.Size() {
op = ssa.OpCopy
} else if tt.Size() < ft.Size() {
// truncation
switch 10*ft.Size() + tt.Size() {
case 21:
op = ssa.OpTrunc16to8
case 41:
op = ssa.OpTrunc32to8
case 42:
op = ssa.OpTrunc32to16
case 81:
op = ssa.OpTrunc64to8
case 82:
op = ssa.OpTrunc64to16
case 84:
op = ssa.OpTrunc64to32
default:
s.Fatalf("weird integer truncation %v -> %v", ft, tt)
}
} else if ft.IsSigned() {
// sign extension
switch 10*ft.Size() + tt.Size() {
case 12:
op = ssa.OpSignExt8to16
case 14:
op = ssa.OpSignExt8to32
case 18:
op = ssa.OpSignExt8to64
case 24:
op = ssa.OpSignExt16to32
case 28:
op = ssa.OpSignExt16to64
case 48:
op = ssa.OpSignExt32to64
default:
s.Fatalf("bad integer sign extension %v -> %v", ft, tt)
}
} else {
// zero extension
switch 10*ft.Size() + tt.Size() {
case 12:
op = ssa.OpZeroExt8to16
case 14:
op = ssa.OpZeroExt8to32
case 18:
op = ssa.OpZeroExt8to64
case 24:
op = ssa.OpZeroExt16to32
case 28:
op = ssa.OpZeroExt16to64
case 48:
op = ssa.OpZeroExt32to64
default:
s.Fatalf("weird integer sign extension %v -> %v", ft, tt)
}
}
return s.newValue1(op, n.Type(), x)
}
if ft.IsFloat() || tt.IsFloat() {
conv, ok := fpConvOpToSSA[twoTypes{s.concreteEtype(ft), s.concreteEtype(tt)}]
if s.config.RegSize == 4 && Arch.LinkArch.Family != sys.MIPS && !s.softFloat {
if conv1, ok1 := fpConvOpToSSA32[twoTypes{s.concreteEtype(ft), s.concreteEtype(tt)}]; ok1 {
conv = conv1
}
}
if Arch.LinkArch.Family == sys.ARM64 || Arch.LinkArch.Family == sys.Wasm || Arch.LinkArch.Family == sys.S390X || s.softFloat {
if conv1, ok1 := uint64fpConvOpToSSA[twoTypes{s.concreteEtype(ft), s.concreteEtype(tt)}]; ok1 {
conv = conv1
}
}
if Arch.LinkArch.Family == sys.MIPS && !s.softFloat {
if ft.Size() == 4 && ft.IsInteger() && !ft.IsSigned() {
// tt is float32 or float64, and ft is also unsigned
if tt.Size() == 4 {
return s.uint32Tofloat32(n, x, ft, tt)
}
if tt.Size() == 8 {
return s.uint32Tofloat64(n, x, ft, tt)
}
} else if tt.Size() == 4 && tt.IsInteger() && !tt.IsSigned() {
// ft is float32 or float64, and tt is unsigned integer
if ft.Size() == 4 {
return s.float32ToUint32(n, x, ft, tt)
}
if ft.Size() == 8 {
return s.float64ToUint32(n, x, ft, tt)
}
}
}
if !ok {
s.Fatalf("weird float conversion %v -> %v", ft, tt)
}
op1, op2, it := conv.op1, conv.op2, conv.intermediateType
if op1 != ssa.OpInvalid && op2 != ssa.OpInvalid {
// normal case, not tripping over unsigned 64
if op1 == ssa.OpCopy {
if op2 == ssa.OpCopy {
return x
}
return s.newValueOrSfCall1(op2, n.Type(), x)
}
if op2 == ssa.OpCopy {
return s.newValueOrSfCall1(op1, n.Type(), x)
}
return s.newValueOrSfCall1(op2, n.Type(), s.newValueOrSfCall1(op1, types.Types[it], x))
}
// Tricky 64-bit unsigned cases.
if ft.IsInteger() {
// tt is float32 or float64, and ft is also unsigned
if tt.Size() == 4 {
return s.uint64Tofloat32(n, x, ft, tt)
}
if tt.Size() == 8 {
return s.uint64Tofloat64(n, x, ft, tt)
}
s.Fatalf("weird unsigned integer to float conversion %v -> %v", ft, tt)
}
// ft is float32 or float64, and tt is unsigned integer
if ft.Size() == 4 {
return s.float32ToUint64(n, x, ft, tt)
}
if ft.Size() == 8 {
return s.float64ToUint64(n, x, ft, tt)
}
s.Fatalf("weird float to unsigned integer conversion %v -> %v", ft, tt)
return nil
}
if ft.IsComplex() && tt.IsComplex() {
var op ssa.Op
if ft.Size() == tt.Size() {
switch ft.Size() {
case 8:
op = ssa.OpRound32F
case 16:
op = ssa.OpRound64F
default:
s.Fatalf("weird complex conversion %v -> %v", ft, tt)
}
} else if ft.Size() == 8 && tt.Size() == 16 {
op = ssa.OpCvt32Fto64F
} else if ft.Size() == 16 && tt.Size() == 8 {
op = ssa.OpCvt64Fto32F
} else {
s.Fatalf("weird complex conversion %v -> %v", ft, tt)
}
ftp := types.FloatForComplex(ft)
ttp := types.FloatForComplex(tt)
return s.newValue2(ssa.OpComplexMake, tt,
s.newValueOrSfCall1(op, ttp, s.newValue1(ssa.OpComplexReal, ftp, x)),
s.newValueOrSfCall1(op, ttp, s.newValue1(ssa.OpComplexImag, ftp, x)))
}
s.Fatalf("unhandled OCONV %s -> %s", n.X.Type().Kind(), n.Type().Kind())
return nil
return s.conv(n, x, n.X.Type(), n.Type())
case ir.ODOTTYPE:
n := n.(*ir.TypeAssertExpr)

View File

@@ -73,7 +73,7 @@ func embedKind(typ *types.Type) int {
if typ.Kind() == types.TSTRING {
return embedString
}
if typ.Sym() == nil && typ.IsSlice() && typ.Elem().Kind() == types.TUINT8 {
if typ.IsSlice() && typ.Elem().Kind() == types.TUINT8 {
return embedBytes
}
return embedUnknown

View File

@@ -1222,12 +1222,14 @@ func (r *importReader) node() ir.Node {
switch op {
case ir.ODOT, ir.ODOTPTR, ir.ODOTINTER:
n.Selection = r.exoticField()
case ir.ODOTMETH, ir.OCALLPART, ir.OMETHEXPR:
case ir.OMETHEXPR:
n = typecheckMethodExpr(n).(*ir.SelectorExpr)
case ir.ODOTMETH, ir.OCALLPART:
// These require a Lookup to link to the correct declaration.
rcvrType := expr.Type()
typ := n.Type()
n.Selection = Lookdot(n, rcvrType, 1)
if op == ir.OCALLPART || op == ir.OMETHEXPR {
if op == ir.OCALLPART {
// Lookdot clobbers the opcode and type, undo that.
n.SetOp(op)
n.SetType(typ)

View File

@@ -383,10 +383,11 @@ func tcSelect(sel *ir.SelectStmt) {
n := Stmt(ncase.Comm)
ncase.Comm = n
oselrecv2 := func(dst, recv ir.Node, def bool) {
n := ir.NewAssignListStmt(n.Pos(), ir.OSELRECV2, []ir.Node{dst, ir.BlankNode}, []ir.Node{recv})
n.Def = def
n.SetTypecheck(1)
ncase.Comm = n
selrecv := ir.NewAssignListStmt(n.Pos(), ir.OSELRECV2, []ir.Node{dst, ir.BlankNode}, []ir.Node{recv})
selrecv.Def = def
selrecv.SetTypecheck(1)
selrecv.SetInit(n.Init())
ncase.Comm = selrecv
}
switch n.Op() {
default:

View File

@@ -4,12 +4,15 @@ go 1.17
require (
github.com/google/pprof v0.0.0-20210506205249-923b5ab0fc1a
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639 // indirect
golang.org/x/arch v0.0.0-20210502124803-cbf565b21d1e
golang.org/x/crypto v0.0.0-20210503195802-e9a32991a82e // indirect
golang.org/x/mod v0.4.3-0.20210608190319-0f08993efd8a
golang.org/x/sys v0.0.0-20210511113859-b0526f3d8744 // indirect
golang.org/x/mod v0.5.1
golang.org/x/term v0.0.0-20210503060354-a79de5458b56
golang.org/x/tools v0.1.2-0.20210519160823-49064d2332f9
)
require (
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639 // indirect
golang.org/x/crypto v0.0.0-20210503195802-e9a32991a82e // indirect
golang.org/x/sys v0.0.0-20210511113859-b0526f3d8744 // indirect
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
)

View File

@@ -13,8 +13,8 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U
golang.org/x/crypto v0.0.0-20210503195802-e9a32991a82e h1:8foAy0aoO5GkqCvAEJ4VC4P3zksTg4X4aJCDpZzmgQI=
golang.org/x/crypto v0.0.0-20210503195802-e9a32991a82e/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.3-0.20210608190319-0f08993efd8a h1:e8qnjKz4EE6OjRki9wTadWSIogINvq10sMcuBRORxMY=
golang.org/x/mod v0.4.3-0.20210608190319-0f08993efd8a/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
golang.org/x/mod v0.5.1 h1:OJxoQ/rynoF0dcCdI7cLPktw/hR2cueqYfjm43oqK38=
golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
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-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=

View File

@@ -2,17 +2,51 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Copied from Go distribution src/go/build/build.go, syslist.go
// Copied from Go distribution src/go/build/build.go, syslist.go.
// That package does not export the ability to process raw file data,
// although we could fake it with an appropriate build.Context
// and a lot of unwrapping.
// More importantly, that package does not implement the tags["*"]
// special case, in which both tag and !tag are considered to be true
// for essentially all tags (except "ignore").
//
// If we added this API to go/build directly, we wouldn't need this
// file anymore, but this API is not terribly general-purpose and we
// don't really want to commit to any public form of it, nor do we
// want to move the core parts of go/build into a top-level internal package.
// These details change very infrequently, so the copy is fine.
package imports
import (
"bytes"
"errors"
"fmt"
"go/build/constraint"
"strings"
"unicode"
)
var slashslash = []byte("//")
var (
bSlashSlash = []byte("//")
bStarSlash = []byte("*/")
bSlashStar = []byte("/*")
bPlusBuild = []byte("+build")
goBuildComment = []byte("//go:build")
errGoBuildWithoutBuild = errors.New("//go:build comment without // +build comment")
errMultipleGoBuild = errors.New("multiple //go:build comments")
)
func isGoBuildComment(line []byte) bool {
if !bytes.HasPrefix(line, goBuildComment) {
return false
}
line = bytes.TrimSpace(line)
rest := line[len(goBuildComment):]
return len(rest) == 0 || len(bytes.TrimSpace(rest)) < len(rest)
}
// ShouldBuild reports whether it is okay to use this file,
// The rule is that in the file's leading run of // comments
@@ -34,90 +68,124 @@ var slashslash = []byte("//")
// in any build.
//
func ShouldBuild(content []byte, tags map[string]bool) bool {
// Pass 1. Identify leading run of // comments and blank lines,
// Identify leading run of // comments and blank lines,
// which must be followed by a blank line.
end := 0
p := content
for len(p) > 0 {
line := p
if i := bytes.IndexByte(line, '\n'); i >= 0 {
line, p = line[:i], p[i+1:]
} else {
p = p[len(p):]
}
line = bytes.TrimSpace(line)
if len(line) == 0 { // Blank line
end = len(content) - len(p)
continue
}
if !bytes.HasPrefix(line, slashslash) { // Not comment line
break
}
// Also identify any //go:build comments.
content, goBuild, _, err := parseFileHeader(content)
if err != nil {
return false
}
content = content[:end]
// Pass 2. Process each line in the run.
p = content
allok := true
for len(p) > 0 {
line := p
if i := bytes.IndexByte(line, '\n'); i >= 0 {
line, p = line[:i], p[i+1:]
} else {
p = p[len(p):]
// If //go:build line is present, it controls.
// Otherwise fall back to +build processing.
var shouldBuild bool
switch {
case goBuild != nil:
x, err := constraint.Parse(string(goBuild))
if err != nil {
return false
}
line = bytes.TrimSpace(line)
if !bytes.HasPrefix(line, slashslash) {
continue
}
line = bytes.TrimSpace(line[len(slashslash):])
if len(line) > 0 && line[0] == '+' {
// Looks like a comment +line.
f := strings.Fields(string(line))
if f[0] == "+build" {
ok := false
for _, tok := range f[1:] {
if matchTags(tok, tags) {
ok = true
}
}
if !ok {
allok = false
shouldBuild = eval(x, tags, true)
default:
shouldBuild = true
p := content
for len(p) > 0 {
line := p
if i := bytes.IndexByte(line, '\n'); i >= 0 {
line, p = line[:i], p[i+1:]
} else {
p = p[len(p):]
}
line = bytes.TrimSpace(line)
if !bytes.HasPrefix(line, bSlashSlash) || !bytes.Contains(line, bPlusBuild) {
continue
}
text := string(line)
if !constraint.IsPlusBuild(text) {
continue
}
if x, err := constraint.Parse(text); err == nil {
if !eval(x, tags, true) {
shouldBuild = false
}
}
}
}
return allok
return shouldBuild
}
// matchTags reports whether the name is one of:
//
// tag (if tags[tag] is true)
// !tag (if tags[tag] is false)
// a comma-separated list of any of these
//
func matchTags(name string, tags map[string]bool) bool {
if name == "" {
return false
func parseFileHeader(content []byte) (trimmed, goBuild []byte, sawBinaryOnly bool, err error) {
end := 0
p := content
ended := false // found non-blank, non-// line, so stopped accepting // +build lines
inSlashStar := false // in /* */ comment
Lines:
for len(p) > 0 {
line := p
if i := bytes.IndexByte(line, '\n'); i >= 0 {
line, p = line[:i], p[i+1:]
} else {
p = p[len(p):]
}
line = bytes.TrimSpace(line)
if len(line) == 0 && !ended { // Blank line
// Remember position of most recent blank line.
// When we find the first non-blank, non-// line,
// this "end" position marks the latest file position
// where a // +build line can appear.
// (It must appear _before_ a blank line before the non-blank, non-// line.
// Yes, that's confusing, which is part of why we moved to //go:build lines.)
// Note that ended==false here means that inSlashStar==false,
// since seeing a /* would have set ended==true.
end = len(content) - len(p)
continue Lines
}
if !bytes.HasPrefix(line, bSlashSlash) { // Not comment line
ended = true
}
if !inSlashStar && isGoBuildComment(line) {
if goBuild != nil {
return nil, nil, false, errMultipleGoBuild
}
goBuild = line
}
Comments:
for len(line) > 0 {
if inSlashStar {
if i := bytes.Index(line, bStarSlash); i >= 0 {
inSlashStar = false
line = bytes.TrimSpace(line[i+len(bStarSlash):])
continue Comments
}
continue Lines
}
if bytes.HasPrefix(line, bSlashSlash) {
continue Lines
}
if bytes.HasPrefix(line, bSlashStar) {
inSlashStar = true
line = bytes.TrimSpace(line[len(bSlashStar):])
continue Comments
}
// Found non-comment text.
break Lines
}
}
if i := strings.Index(name, ","); i >= 0 {
// comma-separated list
ok1 := matchTags(name[:i], tags)
ok2 := matchTags(name[i+1:], tags)
return ok1 && ok2
}
if strings.HasPrefix(name, "!!") { // bad syntax, reject always
return false
}
if strings.HasPrefix(name, "!") { // negation
return len(name) > 1 && matchTag(name[1:], tags, false)
}
return matchTag(name, tags, true)
return content[:end], goBuild, sawBinaryOnly, nil
}
// matchTag reports whether the tag name is valid and satisfied by tags[name]==want.
func matchTag(name string, tags map[string]bool, want bool) bool {
// matchTag reports whether the tag name is valid and tags[name] is true.
// As a special case, if tags["*"] is true and name is not empty or ignore,
// then matchTag will return prefer instead of the actual answer,
// which allows the caller to pretend in that case that most tags are
// both true and false.
func matchTag(name string, tags map[string]bool, prefer bool) bool {
// Tags must be letters, digits, underscores or dots.
// Unlike in Go identifiers, all digits are fine (e.g., "386").
for _, c := range name {
@@ -131,7 +199,7 @@ func matchTag(name string, tags map[string]bool, want bool) bool {
// if we put * in the tags map then all tags
// except "ignore" are considered both present and not
// (so we return true no matter how 'want' is set).
return true
return prefer
}
have := tags[name]
@@ -144,7 +212,25 @@ func matchTag(name string, tags map[string]bool, want bool) bool {
if name == "darwin" {
have = have || tags["ios"]
}
return have == want
return have
}
// eval is like
// x.Eval(func(tag string) bool { return matchTag(tag, tags) })
// except that it implements the special case for tags["*"] meaning
// all tags are both true and false at the same time.
func eval(x constraint.Expr, tags map[string]bool, prefer bool) bool {
switch x := x.(type) {
case *constraint.TagExpr:
return matchTag(x.Tag, tags, prefer)
case *constraint.NotExpr:
return !eval(x.X, tags, !prefer)
case *constraint.AndExpr:
return eval(x.X, tags, prefer) && eval(x.Y, tags, prefer)
case *constraint.OrExpr:
return eval(x.X, tags, prefer) || eval(x.Y, tags, prefer)
}
panic(fmt.Sprintf("unexpected constraint expression %T", x))
}
// MatchFile returns false if the name contains a $GOOS or $GOARCH

View File

@@ -190,8 +190,8 @@ func limiterForEdit(ctx context.Context, rs *Requirements, tryUpgrade, mustSelec
// raiseLimitsForUpgrades increases the module versions in maxVersions to the
// versions that would be needed to allow each of the modules in tryUpgrade
// (individually) and all of the modules in mustSelect (simultaneously) to be
// added as roots.
// (individually or in any combination) and all of the modules in mustSelect
// (simultaneously) to be added as roots.
//
// Versions not present in maxVersion are unrestricted, and it is assumed that
// they will not be promoted to root requirements (and thus will not contribute
@@ -213,18 +213,42 @@ func raiseLimitsForUpgrades(ctx context.Context, maxVersion map[string]string, d
}
}
var eagerUpgrades []module.Version
var (
eagerUpgrades []module.Version
isLazyRootPath map[string]bool
)
if depth == eager {
eagerUpgrades = tryUpgrade
} else {
isLazyRootPath = make(map[string]bool, len(maxVersion))
for p := range maxVersion {
isLazyRootPath[p] = true
}
for _, m := range tryUpgrade {
isLazyRootPath[m.Path] = true
}
for _, m := range mustSelect {
isLazyRootPath[m.Path] = true
}
allowedRoot := map[module.Version]bool{}
var allowRoot func(m module.Version) error
allowRoot = func(m module.Version) error {
if allowedRoot[m] {
return nil
}
allowedRoot[m] = true
if m.Path == Target.Path {
// Target is already considered to be higher than any possible m, so we
// won't be upgrading to it anyway and there is no point scanning its
// dependencies.
continue
return nil
}
allow(m)
summary, err := goModSummary(m)
if err != nil {
return err
@@ -234,12 +258,27 @@ func raiseLimitsForUpgrades(ctx context.Context, maxVersion map[string]string, d
// graph, rather than loading the (potentially-overlapping) subgraph for
// each upgrade individually.
eagerUpgrades = append(eagerUpgrades, m)
continue
return nil
}
for _, r := range summary.require {
allow(r)
if isLazyRootPath[r.Path] {
// r could become a root as the result of an upgrade or downgrade,
// in which case its dependencies will not be pruned out.
// We need to allow those dependencies to be upgraded too.
if err := allowRoot(r); err != nil {
return err
}
} else {
// r will not become a root, so its dependencies don't matter.
// Allow only r itself.
allow(r)
}
}
return nil
}
for _, m := range tryUpgrade {
allowRoot(m)
}
}
@@ -268,16 +307,41 @@ func raiseLimitsForUpgrades(ctx context.Context, maxVersion map[string]string, d
}
}
if len(mustSelect) > 0 {
mustGraph, err := readModGraph(ctx, depth, mustSelect)
// Explicitly allow any (transitive) upgrades implied by mustSelect.
nextRoots := append([]module.Version(nil), mustSelect...)
for nextRoots != nil {
module.Sort(nextRoots)
rs := newRequirements(depth, nextRoots, nil)
nextRoots = nil
rs, mustGraph, err := expandGraph(ctx, rs)
if err != nil {
return err
}
for _, r := range mustGraph.BuildList() {
// Some module in mustSelect requires r, so we must allow at least r.Version
// unless it conflicts with an entry in mustSelect.
// Some module in mustSelect requires r, so we must allow at least
// r.Version (unless it conflicts with another entry in mustSelect, in
// which case we will error out either way).
allow(r)
if isLazyRootPath[r.Path] {
if v, ok := rs.rootSelected(r.Path); ok && r.Version == v {
// r is already a root, so its requirements are already included in
// the build list.
continue
}
// The dependencies in mustSelect may upgrade (or downgrade) an existing
// root to match r, which will remain as a root. However, since r is not
// a root of rs, its dependencies have been pruned out of this build
// list. We need to add it back explicitly so that we allow any
// transitive upgrades that r will pull in.
if nextRoots == nil {
nextRoots = rs.rootModules // already capped
}
nextRoots = append(nextRoots, r)
}
}
}

View File

@@ -142,6 +142,7 @@ var extraEnvKeys = []string{
"GO_TESTING_GOTOOLS", // for gccgo testing
"GCCGO", // for gccgo testing
"GCCGOTOOLDIR", // for gccgo testing
"MallocNanoZone", // Needed to work around an apparent kernel bug in macOS 12; see https://golang.org/issue/49138.
}
// setup sets up the test execution temporary directory and environment.

View File

@@ -0,0 +1,41 @@
# go list all should work with GOOS=linux because all packages build on Linux
env GOOS=linux
go list all
# go list all should work with GOOS=darwin, but it used to fail because
# in the absence of //go:build support, p looked like it needed q
# (p_test.go was not properly excluded), and q was Linux-only.
#
# Also testing with r and s that +build lines keep working.
env GOOS=darwin
go list all
-- go.mod --
go 1.17
module m
-- p/p.go --
package p
-- p/p_test.go --
//go:build linux
package p
import "m/q"
-- q/q_linux.go --
package q
-- r/r.go --
package r
-- r/r_test.go --
// +build linux
package r
import "m/s"
-- s/s_linux.go --
package s

View File

@@ -202,9 +202,9 @@ go mod edit -go=1.17 u/go.mod
go mod edit -go=1.17 w/go.mod
go mod edit -go=1.17 x/go.mod
go mod edit -go=1.17
cp go.mod go.mod.orig
cmp go.mod go.mod.beforetidy
go mod tidy
cmp go.mod go.mod.orig
cmp go.mod go.mod.aftertidy
# With lazy loading, 'go list all' with neither -mod=vendor nor -test should
# match -mod=vendor without -test in 1.15.
@@ -466,3 +466,66 @@ module example.com/x
go 1.15
-- x/x.go --
package x
-- go.mod.beforetidy --
module example.com/main
// Note: this go.mod file initially specifies go 1.15,
// but includes some redundant roots so that it
// also already obeys the 1.17 lazy loading invariants.
go 1.17
require (
example.com/a v0.1.0
example.com/b v0.1.0 // indirect
example.com/q v0.1.0
example.com/r v0.1.0 // indirect
example.com/t v0.1.0
example.com/u v0.1.0 // indirect
)
replace (
example.com/a v0.1.0 => ./a
example.com/b v0.1.0 => ./b
example.com/c v0.1.0 => ./c
example.com/d v0.1.0 => ./d
example.com/q v0.1.0 => ./q
example.com/r v0.1.0 => ./r
example.com/s v0.1.0 => ./s
example.com/t v0.1.0 => ./t
example.com/u v0.1.0 => ./u
example.com/w v0.1.0 => ./w
example.com/x v0.1.0 => ./x
)
-- go.mod.aftertidy --
module example.com/main
// Note: this go.mod file initially specifies go 1.15,
// but includes some redundant roots so that it
// also already obeys the 1.17 lazy loading invariants.
go 1.17
require (
example.com/a v0.1.0
example.com/q v0.1.0
example.com/t v0.1.0
)
require (
example.com/b v0.1.0 // indirect
example.com/r v0.1.0 // indirect
example.com/u v0.1.0 // indirect
)
replace (
example.com/a v0.1.0 => ./a
example.com/b v0.1.0 => ./b
example.com/c v0.1.0 => ./c
example.com/d v0.1.0 => ./d
example.com/q v0.1.0 => ./q
example.com/r v0.1.0 => ./r
example.com/s v0.1.0 => ./s
example.com/t v0.1.0 => ./t
example.com/u v0.1.0 => ./u
example.com/w v0.1.0 => ./w
example.com/x v0.1.0 => ./x
)

View File

@@ -10,7 +10,7 @@ env GO111MODULE=on
env GOPROXY=direct
env GOSUMDB=off
go list -m cloud.google.com/go@master
go list -m cloud.google.com/go@main
! stdout 'v0.0.0-'
-- go.mod --

View File

@@ -0,0 +1,117 @@
# Regression test for https://golang.org/issue/47979:
#
# An argument to 'go get' that results in an upgrade to a different existing
# root should be allowed, and should not panic the 'go' command.
cp go.mod go.mod.orig
# Transitive upgrades from upgraded roots should not prevent
# 'go get -u' from performing upgrades.
cp go.mod.orig go.mod
go get -u -d .
cmp go.mod go.mod.want
# 'go get' of a specific version should allow upgrades of
# every dependency (transitively) required by that version,
# including dependencies that are pulled into the module
# graph by upgrading other root requirements
# (in this case, example.net/indirect).
cp go.mod.orig go.mod
go get -d example.net/a@v0.2.0
cmp go.mod go.mod.want
-- go.mod --
module golang.org/issue47979
go 1.17
replace (
example.net/a v0.1.0 => ./a1
example.net/a v0.2.0 => ./a2
example.net/indirect v0.1.0 => ./indirect1
example.net/indirect v0.2.0 => ./indirect2
example.net/other v0.1.0 => ./other
example.net/other v0.2.0 => ./other
)
require (
example.net/a v0.1.0
example.net/other v0.1.0
)
require example.net/indirect v0.1.0 // indirect
-- go.mod.want --
module golang.org/issue47979
go 1.17
replace (
example.net/a v0.1.0 => ./a1
example.net/a v0.2.0 => ./a2
example.net/indirect v0.1.0 => ./indirect1
example.net/indirect v0.2.0 => ./indirect2
example.net/other v0.1.0 => ./other
example.net/other v0.2.0 => ./other
)
require (
example.net/a v0.2.0
example.net/other v0.2.0
)
require example.net/indirect v0.2.0 // indirect
-- issue.go --
package issue
import _ "example.net/a"
-- useother/useother.go --
package useother
import _ "example.net/other"
-- a1/go.mod --
module example.net/a
go 1.17
require example.net/indirect v0.1.0
-- a1/a.go --
package a
-- a2/go.mod --
module example.net/a
go 1.17
require example.net/indirect v0.2.0
-- a2/a.go --
package a
import "example.net/indirect"
-- indirect1/go.mod --
module example.net/indirect
go 1.17
require example.net/other v0.1.0
-- indirect1/indirect.go --
package indirect
-- indirect2/go.mod --
module example.net/indirect
go 1.17
require example.net/other v0.2.0
-- indirect2/indirect.go --
package indirect
import "example.net/other"
-- other/go.mod --
module example.net/other
go 1.17
-- other/other.go --
package other

View File

@@ -0,0 +1,68 @@
# Check that 'go get -u' will upgrade a dependency (direct or indirect)
# when the main module and the dependency are both lazy.
# Verifies #47768.
# Check that go.mod is tidy, and an upgrade is available.
cp go.mod go.mod.orig
go mod tidy
cmp go.mod go.mod.orig
go list -m -u example.com/lazyupgrade
stdout '^example.com/lazyupgrade v0.1.0 \[v0.1.1\] => ./lazyupgrade@v0.1.0$'
# 'go get -u' on a package that directly imports the dependency should upgrade.
go get -u ./usedirect
go list -m example.com/lazyupgrade
stdout '^example.com/lazyupgrade v0.1.1 => ./lazyupgrade@v0.1.1$'
cp go.mod.orig go.mod
# 'go get -u' on a package that indirectly imports the dependency should upgrade.
go get -u ./useindirect
go list -m example.com/lazyupgrade
stdout '^example.com/lazyupgrade v0.1.1 => ./lazyupgrade@v0.1.1$'
-- go.mod --
module use
go 1.17
require (
direct v0.0.0
example.com/lazyupgrade v0.1.0
)
replace (
direct => ./direct
example.com/lazyupgrade v0.1.0 => ./lazyupgrade@v0.1.0
example.com/lazyupgrade v0.1.1 => ./lazyupgrade@v0.1.1
)
-- usedirect/usedirect.go --
package use
import _ "example.com/lazyupgrade"
-- useindirect/useindirect.go --
package use
import _ "direct"
-- direct/go.mod --
module direct
go 1.17
require example.com/lazyupgrade v0.1.0
-- direct/direct.go --
package direct
import _ "example.com/lazyupgrade"
-- lazyupgrade@v0.1.0/go.mod --
module example.com/lazyupgrade
go 1.17
-- lazyupgrade@v0.1.0/lazyupgrade.go --
package lazyupgrade
-- lazyupgrade@v0.1.1/go.mod --
module example.com/lazyupgrade
go 1.17
-- lazyupgrade@v0.1.1/lazyupgrade.go --
package lazyupgrade

View File

@@ -81,14 +81,14 @@ require (
package x
import _ "rsc.io/quote"
-- go.mod.crlf --
module m
go 1.14
require (
rsc.io/quote v1.5.2
rsc.io/testonly v1.0.0 // indirect
)
module m
go 1.14
require (
rsc.io/quote v1.5.2
rsc.io/testonly v1.0.0 // indirect
)
-- go.mod.unsorted --
module m
@@ -139,10 +139,10 @@ module m
go $goversion
require rsc.io/quote v1.5.2
require (
rsc.io/quote v1.5.2
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c // indirect
rsc.io/sampler v1.3.0 // indirect
rsc.io/testonly v1.0.0 // indirect
)
require golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c // indirect

View File

@@ -72,10 +72,9 @@ go 1.17
replace example.net/indirect v0.1.0 => ./indirect
require (
example.net/ambiguous/nested v0.1.0 // indirect
example.net/indirect v0.1.0
)
require example.net/indirect v0.1.0
require example.net/ambiguous/nested v0.1.0 // indirect
-- all-m.txt --
example.com/m
example.net/ambiguous v0.1.0

View File

@@ -97,10 +97,9 @@ replace (
example.net/requireincompatible v0.1.0 => ./requireincompatible
)
require (
example.com/retract/incompatible v1.0.0 // indirect
example.net/lazy v0.1.0
)
require example.net/lazy v0.1.0
require example.com/retract/incompatible v1.0.0 // indirect
-- incompatible.go --
package incompatible

View File

@@ -602,7 +602,7 @@ func pereloc1(arch *sys.Arch, out *ld.OutBuf, ldr *loader.Loader, s loader.Sym,
rs := r.Xsym
rt := r.Type
if r.Xadd != signext21(r.Xadd) {
if rt == objabi.R_ADDRARM64 && r.Xadd != signext21(r.Xadd) {
// If the relocation target would overflow the addend, then target
// a linker-manufactured label symbol with a smaller addend instead.
label := ldr.Lookup(offsetLabelName(ldr, rs, r.Xadd/peRelocLimit*peRelocLimit), ldr.SymVersion(rs))

View File

@@ -2450,6 +2450,12 @@ func splitTextSections(ctxt *Link) bool {
return (ctxt.IsPPC64() || (ctxt.IsARM64() && ctxt.IsDarwin())) && ctxt.IsExternal()
}
// On Wasm, we reserve 4096 bytes for zero page, then 8192 bytes for wasm_exec.js
// to store command line args and environment variables.
// Data sections starts from at least address 12288.
// Keep in sync with wasm_exec.js.
const wasmMinDataAddr = 4096 + 8192
// address assigns virtual addresses to all segments and sections and
// returns all segments in file order.
func (ctxt *Link) address() []*sym.Segment {
@@ -2459,10 +2465,14 @@ func (ctxt *Link) address() []*sym.Segment {
order = append(order, &Segtext)
Segtext.Rwx = 05
Segtext.Vaddr = va
for _, s := range Segtext.Sections {
for i, s := range Segtext.Sections {
va = uint64(Rnd(int64(va), int64(s.Align)))
s.Vaddr = va
va += s.Length
if ctxt.IsWasm() && i == 0 && va < wasmMinDataAddr {
va = wasmMinDataAddr
}
}
Segtext.Length = va - uint64(*FlagTextAddr)

View File

@@ -132,7 +132,9 @@ func (d *deadcodePass) flood() {
methods = methods[:0]
for i := 0; i < relocs.Count(); i++ {
r := relocs.At(i)
if r.Weak() {
// When build with "-linkshared", we can't tell if the interface
// method in itab will be used or not. Ignore the weak attribute.
if r.Weak() && !(d.ctxt.linkShared && d.ldr.IsItab(symIdx)) {
continue
}
t := r.Type()

View File

@@ -16,6 +16,7 @@ import (
"fmt"
"internal/buildcfg"
"path/filepath"
"runtime"
"sort"
"strings"
)
@@ -1749,7 +1750,7 @@ func asmbElf(ctxt *Link) {
sh.Flags = uint64(elf.SHF_ALLOC)
sh.Addralign = 1
if interpreter == "" && buildcfg.GO_LDSO != "" {
if interpreter == "" && buildcfg.GOOS == runtime.GOOS && buildcfg.GOARCH == runtime.GOARCH && buildcfg.GO_LDSO != "" {
interpreter = buildcfg.GO_LDSO
}

View File

@@ -993,13 +993,31 @@ package main
var x = [1<<25]byte{1<<23: 23, 1<<24: 24}
var addr = [...]*byte{
&x[1<<23-1],
&x[1<<23],
&x[1<<23+1],
&x[1<<24-1],
&x[1<<24],
&x[1<<24+1],
}
func main() {
// check relocations in instructions
check(x[1<<23-1], 0)
check(x[1<<23], 23)
check(x[1<<23+1], 0)
check(x[1<<24-1], 0)
check(x[1<<24], 24)
check(x[1<<24+1], 0)
// check absolute address relocations in data
check(*addr[0], 0)
check(*addr[1], 23)
check(*addr[2], 0)
check(*addr[3], 0)
check(*addr[4], 24)
check(*addr[5], 0)
}
func check(x, y byte) {

View File

@@ -956,170 +956,217 @@ func (f *File) SetRequire(req []*Require) {
// SetRequireSeparateIndirect updates the requirements of f to contain the given
// requirements. Comment contents (except for 'indirect' markings) are retained
// from the first existing requirement for each module path, and block structure
// is maintained as long as the indirect markings match.
// from the first existing requirement for each module path. Like SetRequire,
// SetRequireSeparateIndirect adds requirements for new paths in req,
// updates the version and "// indirect" comment on existing requirements,
// and deletes requirements on paths not in req. Existing duplicate requirements
// are deleted.
//
// Any requirements on paths not already present in the file are added. Direct
// requirements are added to the last block containing *any* other direct
// requirement. Indirect requirements are added to the last block containing
// *only* other indirect requirements. If no suitable block exists, a new one is
// added, with the last block containing a direct dependency (if any)
// immediately before the first block containing only indirect dependencies.
// As its name suggests, SetRequireSeparateIndirect puts direct and indirect
// requirements into two separate blocks, one containing only direct
// requirements, and the other containing only indirect requirements.
// SetRequireSeparateIndirect may move requirements between these two blocks
// when their indirect markings change. However, SetRequireSeparateIndirect
// won't move requirements from other blocks, especially blocks with comments.
//
// The Syntax field is ignored for requirements in the given blocks.
// If the file initially has one uncommented block of requirements,
// SetRequireSeparateIndirect will split it into a direct-only and indirect-only
// block. This aids in the transition to separate blocks.
func (f *File) SetRequireSeparateIndirect(req []*Require) {
type modKey struct {
path string
indirect bool
}
need := make(map[modKey]string)
for _, r := range req {
need[modKey{r.Mod.Path, r.Indirect}] = r.Mod.Version
// hasComments returns whether a line or block has comments
// other than "indirect".
hasComments := func(c Comments) bool {
return len(c.Before) > 0 || len(c.After) > 0 || len(c.Suffix) > 1 ||
(len(c.Suffix) == 1 &&
strings.TrimSpace(strings.TrimPrefix(c.Suffix[0].Token, string(slashSlash))) != "indirect")
}
comments := make(map[string]Comments)
for _, r := range f.Require {
v, ok := need[modKey{r.Mod.Path, r.Indirect}]
if !ok {
if _, ok := need[modKey{r.Mod.Path, !r.Indirect}]; ok {
if _, dup := comments[r.Mod.Path]; !dup {
comments[r.Mod.Path] = r.Syntax.Comments
}
// moveReq adds r to block. If r was in another block, moveReq deletes
// it from that block and transfers its comments.
moveReq := func(r *Require, block *LineBlock) {
var line *Line
if r.Syntax == nil {
line = &Line{Token: []string{AutoQuote(r.Mod.Path), r.Mod.Version}}
r.Syntax = line
if r.Indirect {
r.setIndirect(true)
}
r.markRemoved()
continue
} else {
line = new(Line)
*line = *r.Syntax
if !line.InBlock && len(line.Token) > 0 && line.Token[0] == "require" {
line.Token = line.Token[1:]
}
r.Syntax.Token = nil // Cleanup will delete the old line.
r.Syntax = line
}
r.setVersion(v)
delete(need, modKey{r.Mod.Path, r.Indirect})
line.InBlock = true
block.Line = append(block.Line, line)
}
// Examine existing require lines and blocks.
var (
lastDirectOrMixedBlock Expr
firstIndirectOnlyBlock Expr
lastIndirectOnlyBlock Expr
// We may insert new requirements into the last uncommented
// direct-only and indirect-only blocks. We may also move requirements
// to the opposite block if their indirect markings change.
lastDirectIndex = -1
lastIndirectIndex = -1
// If there are no direct-only or indirect-only blocks, a new block may
// be inserted after the last require line or block.
lastRequireIndex = -1
// If there's only one require line or block, and it's uncommented,
// we'll move its requirements to the direct-only or indirect-only blocks.
requireLineOrBlockCount = 0
// Track the block each requirement belongs to (if any) so we can
// move them later.
lineToBlock = make(map[*Line]*LineBlock)
)
for _, stmt := range f.Syntax.Stmt {
for i, stmt := range f.Syntax.Stmt {
switch stmt := stmt.(type) {
case *Line:
if len(stmt.Token) == 0 || stmt.Token[0] != "require" {
continue
}
if isIndirect(stmt) {
lastIndirectOnlyBlock = stmt
} else {
lastDirectOrMixedBlock = stmt
lastRequireIndex = i
requireLineOrBlockCount++
if !hasComments(stmt.Comments) {
if isIndirect(stmt) {
lastIndirectIndex = i
} else {
lastDirectIndex = i
}
}
case *LineBlock:
if len(stmt.Token) == 0 || stmt.Token[0] != "require" {
continue
}
indirectOnly := true
lastRequireIndex = i
requireLineOrBlockCount++
allDirect := len(stmt.Line) > 0 && !hasComments(stmt.Comments)
allIndirect := len(stmt.Line) > 0 && !hasComments(stmt.Comments)
for _, line := range stmt.Line {
if len(line.Token) == 0 {
continue
}
if !isIndirect(line) {
indirectOnly = false
break
}
}
if indirectOnly {
lastIndirectOnlyBlock = stmt
if firstIndirectOnlyBlock == nil {
firstIndirectOnlyBlock = stmt
}
} else {
lastDirectOrMixedBlock = stmt
}
}
}
isOrContainsStmt := func(stmt Expr, target Expr) bool {
if stmt == target {
return true
}
if stmt, ok := stmt.(*LineBlock); ok {
if target, ok := target.(*Line); ok {
for _, line := range stmt.Line {
if line == target {
return true
}
}
}
}
return false
}
addRequire := func(path, vers string, indirect bool, comments Comments) {
var line *Line
if indirect {
if lastIndirectOnlyBlock != nil {
line = f.Syntax.addLine(lastIndirectOnlyBlock, "require", path, vers)
} else {
// Add a new require block after the last direct-only or mixed "require"
// block (if any).
//
// (f.Syntax.addLine would add the line to an existing "require" block if
// present, but here the existing "require" blocks are all direct-only, so
// we know we need to add a new block instead.)
line = &Line{Token: []string{"require", path, vers}}
lastIndirectOnlyBlock = line
firstIndirectOnlyBlock = line // only block implies first block
if lastDirectOrMixedBlock == nil {
f.Syntax.Stmt = append(f.Syntax.Stmt, line)
lineToBlock[line] = stmt
if hasComments(line.Comments) {
allDirect = false
allIndirect = false
} else if isIndirect(line) {
allDirect = false
} else {
for i, stmt := range f.Syntax.Stmt {
if isOrContainsStmt(stmt, lastDirectOrMixedBlock) {
f.Syntax.Stmt = append(f.Syntax.Stmt, nil) // increase size
copy(f.Syntax.Stmt[i+2:], f.Syntax.Stmt[i+1:]) // shuffle elements up
f.Syntax.Stmt[i+1] = line
break
}
}
allIndirect = false
}
}
if allDirect {
lastDirectIndex = i
}
if allIndirect {
lastIndirectIndex = i
}
}
}
oneFlatUncommentedBlock := requireLineOrBlockCount == 1 &&
!hasComments(*f.Syntax.Stmt[lastRequireIndex].Comment())
// Create direct and indirect blocks if needed. Convert lines into blocks
// if needed. If we end up with an empty block or a one-line block,
// Cleanup will delete it or convert it to a line later.
insertBlock := func(i int) *LineBlock {
block := &LineBlock{Token: []string{"require"}}
f.Syntax.Stmt = append(f.Syntax.Stmt, nil)
copy(f.Syntax.Stmt[i+1:], f.Syntax.Stmt[i:])
f.Syntax.Stmt[i] = block
return block
}
ensureBlock := func(i int) *LineBlock {
switch stmt := f.Syntax.Stmt[i].(type) {
case *LineBlock:
return stmt
case *Line:
block := &LineBlock{
Token: []string{"require"},
Line: []*Line{stmt},
}
stmt.Token = stmt.Token[1:] // remove "require"
stmt.InBlock = true
f.Syntax.Stmt[i] = block
return block
default:
panic(fmt.Sprintf("unexpected statement: %v", stmt))
}
}
var lastDirectBlock *LineBlock
if lastDirectIndex < 0 {
if lastIndirectIndex >= 0 {
lastDirectIndex = lastIndirectIndex
lastIndirectIndex++
} else if lastRequireIndex >= 0 {
lastDirectIndex = lastRequireIndex + 1
} else {
if lastDirectOrMixedBlock != nil {
line = f.Syntax.addLine(lastDirectOrMixedBlock, "require", path, vers)
lastDirectIndex = len(f.Syntax.Stmt)
}
lastDirectBlock = insertBlock(lastDirectIndex)
} else {
lastDirectBlock = ensureBlock(lastDirectIndex)
}
var lastIndirectBlock *LineBlock
if lastIndirectIndex < 0 {
lastIndirectIndex = lastDirectIndex + 1
lastIndirectBlock = insertBlock(lastIndirectIndex)
} else {
lastIndirectBlock = ensureBlock(lastIndirectIndex)
}
// Delete requirements we don't want anymore.
// Update versions and indirect comments on requirements we want to keep.
// If a requirement is in last{Direct,Indirect}Block with the wrong
// indirect marking after this, or if the requirement is in an single
// uncommented mixed block (oneFlatUncommentedBlock), move it to the
// correct block.
//
// Some blocks may be empty after this. Cleanup will remove them.
need := make(map[string]*Require)
for _, r := range req {
need[r.Mod.Path] = r
}
have := make(map[string]*Require)
for _, r := range f.Require {
path := r.Mod.Path
if need[path] == nil || have[path] != nil {
// Requirement not needed, or duplicate requirement. Delete.
r.markRemoved()
continue
}
have[r.Mod.Path] = r
r.setVersion(need[path].Mod.Version)
r.setIndirect(need[path].Indirect)
if need[path].Indirect &&
(oneFlatUncommentedBlock || lineToBlock[r.Syntax] == lastDirectBlock) {
moveReq(r, lastIndirectBlock)
} else if !need[path].Indirect &&
(oneFlatUncommentedBlock || lineToBlock[r.Syntax] == lastIndirectBlock) {
moveReq(r, lastDirectBlock)
}
}
// Add new requirements.
for path, r := range need {
if have[path] == nil {
if r.Indirect {
moveReq(r, lastIndirectBlock)
} else {
// Add a new require block before the first indirect block (if any).
//
// That way if the file initially contains only indirect lines,
// the direct lines still appear before it: we preserve existing
// structure, but only to the extent that that structure already
// reflects the direct/indirect split.
line = &Line{Token: []string{"require", path, vers}}
lastDirectOrMixedBlock = line
if firstIndirectOnlyBlock == nil {
f.Syntax.Stmt = append(f.Syntax.Stmt, line)
} else {
for i, stmt := range f.Syntax.Stmt {
if isOrContainsStmt(stmt, firstIndirectOnlyBlock) {
f.Syntax.Stmt = append(f.Syntax.Stmt, nil) // increase size
copy(f.Syntax.Stmt[i+1:], f.Syntax.Stmt[i:]) // shuffle elements up
f.Syntax.Stmt[i] = line
break
}
}
}
moveReq(r, lastDirectBlock)
}
f.Require = append(f.Require, r)
}
line.Comments.Before = commentsAdd(line.Comments.Before, comments.Before)
line.Comments.Suffix = commentsAdd(line.Comments.Suffix, comments.Suffix)
r := &Require{
Mod: module.Version{Path: path, Version: vers},
Indirect: indirect,
Syntax: line,
}
r.setIndirect(indirect)
f.Require = append(f.Require, r)
}
for k, vers := range need {
addRequire(k.path, vers, k.indirect, comments[k.path])
}
f.SortBlocks()
}

View File

@@ -28,7 +28,7 @@ golang.org/x/arch/x86/x86asm
## explicit; go 1.17
golang.org/x/crypto/ed25519
golang.org/x/crypto/ed25519/internal/edwards25519
# golang.org/x/mod v0.4.3-0.20210608190319-0f08993efd8a
# golang.org/x/mod v0.5.1
## explicit; go 1.17
golang.org/x/mod/internal/lazyregexp
golang.org/x/mod/modfile

View File

@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build darwin || openbsd
// +build darwin openbsd
//go:build (darwin && !ios) || openbsd
// +build darwin,!ios openbsd
package rand

View File

@@ -345,6 +345,15 @@ func NewFile(r io.ReaderAt) (*File, error) {
if err := binary.Read(b, bo, &hdr); err != nil {
return nil, err
}
if hdr.Iundefsym > uint32(len(f.Symtab.Syms)) {
return nil, &FormatError{offset, fmt.Sprintf(
"undefined symbols index in dynamic symbol table command is greater than symbol table length (%d > %d)",
hdr.Iundefsym, len(f.Symtab.Syms)), nil}
} else if hdr.Iundefsym+hdr.Nundefsym > uint32(len(f.Symtab.Syms)) {
return nil, &FormatError{offset, fmt.Sprintf(
"number of undefined symbols after index in dynamic symbol table command is greater than symbol table length (%d > %d)",
hdr.Iundefsym+hdr.Nundefsym, len(f.Symtab.Syms)), nil}
}
dat := make([]byte, hdr.Nindirectsyms*4)
if _, err := r.ReadAt(dat, int64(hdr.Indirectsymoff)); err != nil {
return nil, err

View File

@@ -416,3 +416,10 @@ func TestTypeString(t *testing.T) {
t.Errorf("got %v, want %v", TypeExec.GoString(), "macho.Exec")
}
}
func TestOpenBadDysymCmd(t *testing.T) {
_, err := openObscured("testdata/gcc-amd64-darwin-exec-with-bad-dysym.base64")
if err == nil {
t.Fatal("openObscured did not fail when opening a file with an invalid dynamic symbol table command")
}
}

File diff suppressed because one or more lines are too long

View File

@@ -129,3 +129,43 @@ func TestUninitialized(t *testing.T) {
t.Errorf("in uninitialized embed.FS, . is not a directory")
}
}
var (
//go:embed "testdata/hello.txt"
helloT []T
//go:embed "testdata/hello.txt"
helloUint8 []uint8
//go:embed "testdata/hello.txt"
helloEUint8 []EmbedUint8
//go:embed "testdata/hello.txt"
helloBytes EmbedBytes
//go:embed "testdata/hello.txt"
helloString EmbedString
)
type T byte
type EmbedUint8 uint8
type EmbedBytes []byte
type EmbedString string
// golang.org/issue/47735
func TestAliases(t *testing.T) {
all := testDirAll
want, e := all.ReadFile("testdata/hello.txt")
if e != nil {
t.Fatal("ReadFile:", e)
}
check := func(g interface{}) {
got := reflect.ValueOf(g)
for i := 0; i < got.Len(); i++ {
if byte(got.Index(i).Uint()) != want[i] {
t.Fatalf("got %v want %v", got.Bytes(), want)
}
}
}
check(helloT)
check(helloUint8)
check(helloEUint8)
check(helloBytes)
check(helloString)
}

View File

@@ -4,7 +4,10 @@ go 1.17
require (
golang.org/x/crypto v0.0.0-20210503195802-e9a32991a82e
golang.org/x/net v0.0.0-20210510120150-4163338589ed
golang.org/x/net v0.0.0-20211209100829-84cba5454caf
)
require (
golang.org/x/sys v0.0.0-20210511113859-b0526f3d8744 // indirect
golang.org/x/text v0.3.7-0.20210503195748-5c7c50ebbd4f // indirect
)

View File

@@ -1,8 +1,8 @@
golang.org/x/crypto v0.0.0-20210503195802-e9a32991a82e h1:8foAy0aoO5GkqCvAEJ4VC4P3zksTg4X4aJCDpZzmgQI=
golang.org/x/crypto v0.0.0-20210503195802-e9a32991a82e/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210510120150-4163338589ed h1:p9UgmWI9wKpfYmgaV/IZKGdXc5qEK45tDwwwDyjS26I=
golang.org/x/net v0.0.0-20210510120150-4163338589ed/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211209100829-84cba5454caf h1:Chci/BE/+xVqrcWnObL99NS8gtXyJrhHDlygBQrggHM=
golang.org/x/net v0.0.0-20211209100829-84cba5454caf/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210511113859-b0526f3d8744 h1:yhBbb4IRs2HS9PPlAg6DMC6mUOKexJBNsLf4Z+6En1Q=

View File

@@ -224,7 +224,6 @@ func (check *Checker) exprList(elist []ast.Expr, allowCommaOk bool) (xlist []*op
// exactly one (possibly invalid or comma-ok) value
xlist = []*operand{&x}
if allowCommaOk && (x.mode == mapindex || x.mode == commaok || x.mode == commaerr) {
x.mode = value
x2 := &operand{mode: value, expr: e, typ: Typ[UntypedBool]}
if x.mode == commaerr {
x2.typ = universeError

View File

@@ -343,6 +343,7 @@ func (check *Checker) validType(typ Type, path []Object) typeInfo {
if tn == t.obj {
check.cycleError(path[i:])
t.info = invalid
t.underlying = Typ[Invalid]
return t.info
}
}

View File

@@ -276,7 +276,7 @@ func (check *Checker) collectObjects() {
}
if name == "init" {
check.errorf(d.spec.Name, _InvalidInitDecl, "cannot import package as init - init must be a func")
check.errorf(d.spec, _InvalidInitDecl, "cannot import package as init - init must be a func")
return
}

View File

@@ -0,0 +1,15 @@
// Copyright 2021 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 p
import "unsafe"
type T /* ERROR illegal cycle in declaration of T */ struct {
T
}
func _(t T) {
_ = unsafe.Sizeof(t) // should not go into infinite recursion here
}

View File

@@ -759,6 +759,9 @@ func (check *Checker) newTypeParam(obj *TypeName, index int, bound Type) *_TypeP
func (t *_TypeParam) Bound() *Interface {
iface := asInterface(t.bound)
if iface == nil {
return &emptyInterface
}
// use the type bound position if we have one
pos := token.NoPos
if n, _ := t.bound.(*Named); n != nil {

View File

@@ -2,6 +2,9 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build darwin && !ios
// +build darwin,!ios
package unix
import (

View File

@@ -965,7 +965,6 @@ func (b *cancelTimerBody) Read(p []byte) (n int, err error) {
if err == nil {
return n, nil
}
b.stop()
if err == io.EOF {
return n, err
}

View File

@@ -1353,6 +1353,33 @@ func TestClientTimeoutCancel(t *testing.T) {
}
}
func TestClientTimeoutDoesNotExpire_h1(t *testing.T) { testClientTimeoutDoesNotExpire(t, h1Mode) }
func TestClientTimeoutDoesNotExpire_h2(t *testing.T) { testClientTimeoutDoesNotExpire(t, h2Mode) }
// Issue 49366: if Client.Timeout is set but not hit, no error should be returned.
func testClientTimeoutDoesNotExpire(t *testing.T, h2 bool) {
setParallel(t)
defer afterTest(t)
cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) {
w.Write([]byte("body"))
}))
defer cst.close()
cst.c.Timeout = 1 * time.Hour
req, _ := NewRequest("GET", cst.ts.URL, nil)
res, err := cst.c.Do(req)
if err != nil {
t.Fatal(err)
}
if _, err = io.Copy(io.Discard, res.Body); err != nil {
t.Fatalf("io.Copy(io.Discard, res.Body) = %v, want nil", err)
}
if err = res.Body.Close(); err != nil {
t.Fatalf("res.Body.Close() = %v, want nil", err)
}
}
func TestClientRedirectEatsBody_h1(t *testing.T) { testClientRedirectEatsBody(t, h1Mode) }
func TestClientRedirectEatsBody_h2(t *testing.T) { testClientRedirectEatsBody(t, h2Mode) }
func testClientRedirectEatsBody(t *testing.T, h2 bool) {

View File

@@ -1582,3 +1582,37 @@ func TestH12_WebSocketUpgrade(t *testing.T) {
},
}.run(t)
}
func TestIdentityTransferEncoding_h1(t *testing.T) { testIdentityTransferEncoding(t, h1Mode) }
func TestIdentityTransferEncoding_h2(t *testing.T) { testIdentityTransferEncoding(t, h2Mode) }
func testIdentityTransferEncoding(t *testing.T, h2 bool) {
setParallel(t)
defer afterTest(t)
const body = "body"
cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) {
gotBody, _ := io.ReadAll(r.Body)
if got, want := string(gotBody), body; got != want {
t.Errorf("got request body = %q; want %q", got, want)
}
w.Header().Set("Transfer-Encoding", "identity")
w.WriteHeader(StatusOK)
w.(Flusher).Flush()
io.WriteString(w, body)
}))
defer cst.close()
req, _ := NewRequest("GET", cst.ts.URL, strings.NewReader(body))
res, err := cst.c.Do(req)
if err != nil {
t.Fatal(err)
}
defer res.Body.Close()
gotBody, err := io.ReadAll(res.Body)
if err != nil {
t.Fatal(err)
}
if got, want := string(gotBody), body; got != want {
t.Errorf("got response body = %q; want %q", got, want)
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1404,11 +1404,11 @@ func (cw *chunkWriter) writeHeader(p []byte) {
hasCL = false
}
if w.req.Method == "HEAD" || !bodyAllowedForStatus(code) {
// do nothing
} else if code == StatusNoContent {
if w.req.Method == "HEAD" || !bodyAllowedForStatus(code) || code == StatusNoContent {
// Response has no body.
delHeader("Transfer-Encoding")
} else if hasCL {
// Content-Length has been provided, so no chunking is to be done.
delHeader("Transfer-Encoding")
} else if w.req.ProtoAtLeast(1, 1) {
// HTTP/1.1 or greater: Transfer-Encoding has been set to identity, and no
@@ -1419,6 +1419,7 @@ func (cw *chunkWriter) writeHeader(p []byte) {
if hasTE && te == "identity" {
cw.chunking = false
w.closeAfterReply = true
delHeader("Transfer-Encoding")
} else {
// HTTP/1.1 or greater: use chunked transfer encoding
// to avoid closing the connection at EOF.

View File

@@ -10,6 +10,7 @@ package exec_test
import (
"io"
"os"
"os/exec"
"strconv"
"syscall"
"testing"
@@ -41,3 +42,16 @@ func TestPipePassing(t *testing.T) {
t.Error(err)
}
}
func TestNoInheritHandles(t *testing.T) {
cmd := exec.Command("cmd", "/c exit 88")
cmd.SysProcAttr = &syscall.SysProcAttr{NoInheritHandles: true}
err := cmd.Run()
exitError, ok := err.(*exec.ExitError)
if !ok {
t.Fatalf("got error %v; want ExitError", err)
}
if exitError.ExitCode() != 88 {
t.Fatalf("got exit code %d; want 88", exitError.ExitCode())
}
}

View File

@@ -78,6 +78,7 @@ type pollDesc struct {
// pollReset, pollWait, pollWaitCanceled and runtime·netpollready (IO readiness notification)
// proceed w/o taking the lock. So closing, everr, rg, rd, wg and wd are manipulated
// in a lock-free way by all operations.
// TODO(golang.org/issue/49008): audit these lock-free fields for continued correctness.
// NOTE(dvyukov): the following code uses uintptr to store *g (rg/wg),
// that will blow up when GC starts moving objects.
lock mutex // protects the following fields
@@ -86,11 +87,11 @@ type pollDesc struct {
everr bool // marks event scanning error happened
user uint32 // user settable cookie
rseq uintptr // protects from stale read timers
rg uintptr // pdReady, pdWait, G waiting for read or nil
rg uintptr // pdReady, pdWait, G waiting for read or nil. Accessed atomically.
rt timer // read deadline timer (set if rt.f != nil)
rd int64 // read deadline
wseq uintptr // protects from stale write timers
wg uintptr // pdReady, pdWait, G waiting for write or nil
wg uintptr // pdReady, pdWait, G waiting for write or nil. Accessed atomically.
wt timer // write deadline timer
wd int64 // write deadline
self *pollDesc // storage for indirect interface. See (*pollDesc).makeArg.
@@ -147,20 +148,22 @@ func poll_runtime_isPollServerDescriptor(fd uintptr) bool {
func poll_runtime_pollOpen(fd uintptr) (*pollDesc, int) {
pd := pollcache.alloc()
lock(&pd.lock)
if pd.wg != 0 && pd.wg != pdReady {
wg := atomic.Loaduintptr(&pd.wg)
if wg != 0 && wg != pdReady {
throw("runtime: blocked write on free polldesc")
}
if pd.rg != 0 && pd.rg != pdReady {
rg := atomic.Loaduintptr(&pd.rg)
if rg != 0 && rg != pdReady {
throw("runtime: blocked read on free polldesc")
}
pd.fd = fd
pd.closing = false
pd.everr = false
pd.rseq++
pd.rg = 0
atomic.Storeuintptr(&pd.rg, 0)
pd.rd = 0
pd.wseq++
pd.wg = 0
atomic.Storeuintptr(&pd.wg, 0)
pd.wd = 0
pd.self = pd
unlock(&pd.lock)
@@ -178,10 +181,12 @@ func poll_runtime_pollClose(pd *pollDesc) {
if !pd.closing {
throw("runtime: close polldesc w/o unblock")
}
if pd.wg != 0 && pd.wg != pdReady {
wg := atomic.Loaduintptr(&pd.wg)
if wg != 0 && wg != pdReady {
throw("runtime: blocked write on closing polldesc")
}
if pd.rg != 0 && pd.rg != pdReady {
rg := atomic.Loaduintptr(&pd.rg)
if rg != 0 && rg != pdReady {
throw("runtime: blocked read on closing polldesc")
}
netpollclose(pd.fd)
@@ -205,9 +210,9 @@ func poll_runtime_pollReset(pd *pollDesc, mode int) int {
return errcode
}
if mode == 'r' {
pd.rg = 0
atomic.Storeuintptr(&pd.rg, 0)
} else if mode == 'w' {
pd.wg = 0
atomic.Storeuintptr(&pd.wg, 0)
}
return pollNoError
}
@@ -417,6 +422,8 @@ func netpollgoready(gp *g, traceskip int) {
// returns true if IO is ready, or false if timedout or closed
// waitio - wait only for completed IO, ignore errors
// Concurrent calls to netpollblock in the same mode are forbidden, as pollDesc
// can hold only a single waiting goroutine for each mode.
func netpollblock(pd *pollDesc, mode int32, waitio bool) bool {
gpp := &pd.rg
if mode == 'w' {
@@ -425,17 +432,19 @@ func netpollblock(pd *pollDesc, mode int32, waitio bool) bool {
// set the gpp semaphore to pdWait
for {
old := *gpp
if old == pdReady {
*gpp = 0
// Consume notification if already ready.
if atomic.Casuintptr(gpp, pdReady, 0) {
return true
}
if old != 0 {
throw("runtime: double wait")
}
if atomic.Casuintptr(gpp, 0, pdWait) {
break
}
// Double check that this isn't corrupt; otherwise we'd loop
// forever.
if v := atomic.Loaduintptr(gpp); v != pdReady && v != 0 {
throw("runtime: double wait")
}
}
// need to recheck error states after setting gpp to pdWait
@@ -459,7 +468,7 @@ func netpollunblock(pd *pollDesc, mode int32, ioready bool) *g {
}
for {
old := *gpp
old := atomic.Loaduintptr(gpp)
if old == pdReady {
return nil
}

View File

@@ -4686,7 +4686,7 @@ func sigprof(pc, sp, lr uintptr, gp *g, mp *m) {
return
}
// On mips{,le}, 64bit atomics are emulated with spinlocks, in
// On mips{,le}/arm, 64bit atomics are emulated with spinlocks, in
// runtime/internal/atomic. If SIGPROF arrives while the program is inside
// the critical section, it creates a deadlock (when writing the sample).
// As a workaround, create a counter of SIGPROFs while in critical section
@@ -4699,6 +4699,13 @@ func sigprof(pc, sp, lr uintptr, gp *g, mp *m) {
return
}
}
if GOARCH == "arm" && goarm < 7 && GOOS == "linux" && pc&0xffff0000 == 0xffff0000 {
// runtime/internal/atomic functions call into kernel
// helpers on arm < 7. See
// runtime/internal/atomic/sys_linux_arm.s.
cpuprof.lostAtomic++
return
}
}
// Profiling runs concurrently with GC, so it must not allocate.

View File

@@ -105,28 +105,38 @@ func syscallNoErr()
//go:nosplit
//go:cgo_unsafe_args
func pthread_attr_init(attr *pthreadattr) int32 {
return libcCall(unsafe.Pointer(abi.FuncPCABI0(pthread_attr_init_trampoline)), unsafe.Pointer(&attr))
ret := libcCall(unsafe.Pointer(abi.FuncPCABI0(pthread_attr_init_trampoline)), unsafe.Pointer(&attr))
KeepAlive(attr)
return ret
}
func pthread_attr_init_trampoline()
//go:nosplit
//go:cgo_unsafe_args
func pthread_attr_getstacksize(attr *pthreadattr, size *uintptr) int32 {
return libcCall(unsafe.Pointer(abi.FuncPCABI0(pthread_attr_getstacksize_trampoline)), unsafe.Pointer(&attr))
ret := libcCall(unsafe.Pointer(abi.FuncPCABI0(pthread_attr_getstacksize_trampoline)), unsafe.Pointer(&attr))
KeepAlive(attr)
KeepAlive(size)
return ret
}
func pthread_attr_getstacksize_trampoline()
//go:nosplit
//go:cgo_unsafe_args
func pthread_attr_setdetachstate(attr *pthreadattr, state int) int32 {
return libcCall(unsafe.Pointer(abi.FuncPCABI0(pthread_attr_setdetachstate_trampoline)), unsafe.Pointer(&attr))
ret := libcCall(unsafe.Pointer(abi.FuncPCABI0(pthread_attr_setdetachstate_trampoline)), unsafe.Pointer(&attr))
KeepAlive(attr)
return ret
}
func pthread_attr_setdetachstate_trampoline()
//go:nosplit
//go:cgo_unsafe_args
func pthread_create(attr *pthreadattr, start uintptr, arg unsafe.Pointer) int32 {
return libcCall(unsafe.Pointer(abi.FuncPCABI0(pthread_create_trampoline)), unsafe.Pointer(&attr))
ret := libcCall(unsafe.Pointer(abi.FuncPCABI0(pthread_create_trampoline)), unsafe.Pointer(&attr))
KeepAlive(attr)
KeepAlive(arg) // Just for consistency. Arg of course needs to be kept alive for the start function.
return ret
}
func pthread_create_trampoline()
@@ -175,6 +185,7 @@ func mmap_trampoline()
//go:cgo_unsafe_args
func munmap(addr unsafe.Pointer, n uintptr) {
libcCall(unsafe.Pointer(abi.FuncPCABI0(munmap_trampoline)), unsafe.Pointer(&addr))
KeepAlive(addr) // Just for consistency. Hopefully addr is not a Go address.
}
func munmap_trampoline()
@@ -182,6 +193,7 @@ func munmap_trampoline()
//go:cgo_unsafe_args
func madvise(addr unsafe.Pointer, n uintptr, flags int32) {
libcCall(unsafe.Pointer(abi.FuncPCABI0(madvise_trampoline)), unsafe.Pointer(&addr))
KeepAlive(addr) // Just for consistency. Hopefully addr is not a Go address.
}
func madvise_trampoline()
@@ -189,13 +201,16 @@ func madvise_trampoline()
//go:cgo_unsafe_args
func mlock(addr unsafe.Pointer, n uintptr) {
libcCall(unsafe.Pointer(abi.FuncPCABI0(mlock_trampoline)), unsafe.Pointer(&addr))
KeepAlive(addr) // Just for consistency. Hopefully addr is not a Go address.
}
func mlock_trampoline()
//go:nosplit
//go:cgo_unsafe_args
func read(fd int32, p unsafe.Pointer, n int32) int32 {
return libcCall(unsafe.Pointer(abi.FuncPCABI0(read_trampoline)), unsafe.Pointer(&fd))
ret := libcCall(unsafe.Pointer(abi.FuncPCABI0(read_trampoline)), unsafe.Pointer(&fd))
KeepAlive(p)
return ret
}
func read_trampoline()
@@ -239,14 +254,18 @@ func usleep_no_g(usec uint32) {
//go:nosplit
//go:cgo_unsafe_args
func write1(fd uintptr, p unsafe.Pointer, n int32) int32 {
return libcCall(unsafe.Pointer(abi.FuncPCABI0(write_trampoline)), unsafe.Pointer(&fd))
ret := libcCall(unsafe.Pointer(abi.FuncPCABI0(write_trampoline)), unsafe.Pointer(&fd))
KeepAlive(p)
return ret
}
func write_trampoline()
//go:nosplit
//go:cgo_unsafe_args
func open(name *byte, mode, perm int32) (ret int32) {
return libcCall(unsafe.Pointer(abi.FuncPCABI0(open_trampoline)), unsafe.Pointer(&name))
ret = libcCall(unsafe.Pointer(abi.FuncPCABI0(open_trampoline)), unsafe.Pointer(&name))
KeepAlive(name)
return
}
func open_trampoline()
@@ -285,6 +304,8 @@ func walltime_trampoline()
//go:cgo_unsafe_args
func sigaction(sig uint32, new *usigactiont, old *usigactiont) {
libcCall(unsafe.Pointer(abi.FuncPCABI0(sigaction_trampoline)), unsafe.Pointer(&sig))
KeepAlive(new)
KeepAlive(old)
}
func sigaction_trampoline()
@@ -292,6 +313,8 @@ func sigaction_trampoline()
//go:cgo_unsafe_args
func sigprocmask(how uint32, new *sigset, old *sigset) {
libcCall(unsafe.Pointer(abi.FuncPCABI0(sigprocmask_trampoline)), unsafe.Pointer(&how))
KeepAlive(new)
KeepAlive(old)
}
func sigprocmask_trampoline()
@@ -306,6 +329,8 @@ func sigaltstack(new *stackt, old *stackt) {
new.ss_size = 32768
}
libcCall(unsafe.Pointer(abi.FuncPCABI0(sigaltstack_trampoline)), unsafe.Pointer(&new))
KeepAlive(new)
KeepAlive(old)
}
func sigaltstack_trampoline()
@@ -320,20 +345,32 @@ func raiseproc_trampoline()
//go:cgo_unsafe_args
func setitimer(mode int32, new, old *itimerval) {
libcCall(unsafe.Pointer(abi.FuncPCABI0(setitimer_trampoline)), unsafe.Pointer(&mode))
KeepAlive(new)
KeepAlive(old)
}
func setitimer_trampoline()
//go:nosplit
//go:cgo_unsafe_args
func sysctl(mib *uint32, miblen uint32, oldp *byte, oldlenp *uintptr, newp *byte, newlen uintptr) int32 {
return libcCall(unsafe.Pointer(abi.FuncPCABI0(sysctl_trampoline)), unsafe.Pointer(&mib))
ret := libcCall(unsafe.Pointer(abi.FuncPCABI0(sysctl_trampoline)), unsafe.Pointer(&mib))
KeepAlive(mib)
KeepAlive(oldp)
KeepAlive(oldlenp)
KeepAlive(newp)
return ret
}
func sysctl_trampoline()
//go:nosplit
//go:cgo_unsafe_args
func sysctlbyname(name *byte, oldp *byte, oldlenp *uintptr, newp *byte, newlen uintptr) int32 {
return libcCall(unsafe.Pointer(abi.FuncPCABI0(sysctlbyname_trampoline)), unsafe.Pointer(&name))
ret := libcCall(unsafe.Pointer(abi.FuncPCABI0(sysctlbyname_trampoline)), unsafe.Pointer(&name))
KeepAlive(name)
KeepAlive(oldp)
KeepAlive(oldlenp)
KeepAlive(newp)
return ret
}
func sysctlbyname_trampoline()
@@ -355,56 +392,79 @@ func kqueue_trampoline()
//go:nosplit
//go:cgo_unsafe_args
func kevent(kq int32, ch *keventt, nch int32, ev *keventt, nev int32, ts *timespec) int32 {
return libcCall(unsafe.Pointer(abi.FuncPCABI0(kevent_trampoline)), unsafe.Pointer(&kq))
ret := libcCall(unsafe.Pointer(abi.FuncPCABI0(kevent_trampoline)), unsafe.Pointer(&kq))
KeepAlive(ch)
KeepAlive(ev)
KeepAlive(ts)
return ret
}
func kevent_trampoline()
//go:nosplit
//go:cgo_unsafe_args
func pthread_mutex_init(m *pthreadmutex, attr *pthreadmutexattr) int32 {
return libcCall(unsafe.Pointer(abi.FuncPCABI0(pthread_mutex_init_trampoline)), unsafe.Pointer(&m))
ret := libcCall(unsafe.Pointer(abi.FuncPCABI0(pthread_mutex_init_trampoline)), unsafe.Pointer(&m))
KeepAlive(m)
KeepAlive(attr)
return ret
}
func pthread_mutex_init_trampoline()
//go:nosplit
//go:cgo_unsafe_args
func pthread_mutex_lock(m *pthreadmutex) int32 {
return libcCall(unsafe.Pointer(abi.FuncPCABI0(pthread_mutex_lock_trampoline)), unsafe.Pointer(&m))
ret := libcCall(unsafe.Pointer(abi.FuncPCABI0(pthread_mutex_lock_trampoline)), unsafe.Pointer(&m))
KeepAlive(m)
return ret
}
func pthread_mutex_lock_trampoline()
//go:nosplit
//go:cgo_unsafe_args
func pthread_mutex_unlock(m *pthreadmutex) int32 {
return libcCall(unsafe.Pointer(abi.FuncPCABI0(pthread_mutex_unlock_trampoline)), unsafe.Pointer(&m))
ret := libcCall(unsafe.Pointer(abi.FuncPCABI0(pthread_mutex_unlock_trampoline)), unsafe.Pointer(&m))
KeepAlive(m)
return ret
}
func pthread_mutex_unlock_trampoline()
//go:nosplit
//go:cgo_unsafe_args
func pthread_cond_init(c *pthreadcond, attr *pthreadcondattr) int32 {
return libcCall(unsafe.Pointer(abi.FuncPCABI0(pthread_cond_init_trampoline)), unsafe.Pointer(&c))
ret := libcCall(unsafe.Pointer(abi.FuncPCABI0(pthread_cond_init_trampoline)), unsafe.Pointer(&c))
KeepAlive(c)
KeepAlive(attr)
return ret
}
func pthread_cond_init_trampoline()
//go:nosplit
//go:cgo_unsafe_args
func pthread_cond_wait(c *pthreadcond, m *pthreadmutex) int32 {
return libcCall(unsafe.Pointer(abi.FuncPCABI0(pthread_cond_wait_trampoline)), unsafe.Pointer(&c))
ret := libcCall(unsafe.Pointer(abi.FuncPCABI0(pthread_cond_wait_trampoline)), unsafe.Pointer(&c))
KeepAlive(c)
KeepAlive(m)
return ret
}
func pthread_cond_wait_trampoline()
//go:nosplit
//go:cgo_unsafe_args
func pthread_cond_timedwait_relative_np(c *pthreadcond, m *pthreadmutex, t *timespec) int32 {
return libcCall(unsafe.Pointer(abi.FuncPCABI0(pthread_cond_timedwait_relative_np_trampoline)), unsafe.Pointer(&c))
ret := libcCall(unsafe.Pointer(abi.FuncPCABI0(pthread_cond_timedwait_relative_np_trampoline)), unsafe.Pointer(&c))
KeepAlive(c)
KeepAlive(m)
KeepAlive(t)
return ret
}
func pthread_cond_timedwait_relative_np_trampoline()
//go:nosplit
//go:cgo_unsafe_args
func pthread_cond_signal(c *pthreadcond) int32 {
return libcCall(unsafe.Pointer(abi.FuncPCABI0(pthread_cond_signal_trampoline)), unsafe.Pointer(&c))
ret := libcCall(unsafe.Pointer(abi.FuncPCABI0(pthread_cond_signal_trampoline)), unsafe.Pointer(&c))
KeepAlive(c)
return ret
}
func pthread_cond_signal_trampoline()

View File

@@ -14,7 +14,9 @@ import (
//go:nosplit
//go:cgo_unsafe_args
func g0_pthread_key_create(k *pthreadkey, destructor uintptr) int32 {
return asmcgocall(unsafe.Pointer(funcPC(pthread_key_create_trampoline)), unsafe.Pointer(&k))
ret := asmcgocall(unsafe.Pointer(funcPC(pthread_key_create_trampoline)), unsafe.Pointer(&k))
KeepAlive(k)
return ret
}
func pthread_key_create_trampoline()

View File

@@ -15,35 +15,47 @@ import "unsafe"
//go:nosplit
//go:cgo_unsafe_args
func pthread_attr_init(attr *pthreadattr) int32 {
return libcCall(unsafe.Pointer(funcPC(pthread_attr_init_trampoline)), unsafe.Pointer(&attr))
ret := libcCall(unsafe.Pointer(funcPC(pthread_attr_init_trampoline)), unsafe.Pointer(&attr))
KeepAlive(attr)
return ret
}
func pthread_attr_init_trampoline()
//go:nosplit
//go:cgo_unsafe_args
func pthread_attr_destroy(attr *pthreadattr) int32 {
return libcCall(unsafe.Pointer(funcPC(pthread_attr_destroy_trampoline)), unsafe.Pointer(&attr))
ret := libcCall(unsafe.Pointer(funcPC(pthread_attr_destroy_trampoline)), unsafe.Pointer(&attr))
KeepAlive(attr)
return ret
}
func pthread_attr_destroy_trampoline()
//go:nosplit
//go:cgo_unsafe_args
func pthread_attr_getstacksize(attr *pthreadattr, size *uintptr) int32 {
return libcCall(unsafe.Pointer(funcPC(pthread_attr_getstacksize_trampoline)), unsafe.Pointer(&attr))
ret := libcCall(unsafe.Pointer(funcPC(pthread_attr_getstacksize_trampoline)), unsafe.Pointer(&attr))
KeepAlive(attr)
KeepAlive(size)
return ret
}
func pthread_attr_getstacksize_trampoline()
//go:nosplit
//go:cgo_unsafe_args
func pthread_attr_setdetachstate(attr *pthreadattr, state int) int32 {
return libcCall(unsafe.Pointer(funcPC(pthread_attr_setdetachstate_trampoline)), unsafe.Pointer(&attr))
ret := libcCall(unsafe.Pointer(funcPC(pthread_attr_setdetachstate_trampoline)), unsafe.Pointer(&attr))
KeepAlive(attr)
return ret
}
func pthread_attr_setdetachstate_trampoline()
//go:nosplit
//go:cgo_unsafe_args
func pthread_create(attr *pthreadattr, start uintptr, arg unsafe.Pointer) int32 {
return libcCall(unsafe.Pointer(funcPC(pthread_create_trampoline)), unsafe.Pointer(&attr))
ret := libcCall(unsafe.Pointer(funcPC(pthread_create_trampoline)), unsafe.Pointer(&attr))
KeepAlive(attr)
KeepAlive(arg) // Just for consistency. Arg of course needs to be kept alive for the start function.
return ret
}
func pthread_create_trampoline()

View File

@@ -12,7 +12,10 @@ import "unsafe"
//go:nosplit
//go:cgo_unsafe_args
func thrsleep(ident uintptr, clock_id int32, tsp *timespec, lock uintptr, abort *uint32) int32 {
return libcCall(unsafe.Pointer(funcPC(thrsleep_trampoline)), unsafe.Pointer(&ident))
ret := libcCall(unsafe.Pointer(funcPC(thrsleep_trampoline)), unsafe.Pointer(&ident))
KeepAlive(tsp)
KeepAlive(abort)
return ret
}
func thrsleep_trampoline()

View File

@@ -54,6 +54,7 @@ func mmap(addr unsafe.Pointer, n uintptr, prot, flags, fd int32, off uint32) (un
ret2 int
}{addr, n, prot, flags, fd, off, nil, 0}
libcCall(unsafe.Pointer(funcPC(mmap_trampoline)), unsafe.Pointer(&args))
KeepAlive(addr) // Just for consistency. Hopefully addr is not a Go address.
return args.ret1, args.ret2
}
func mmap_trampoline()
@@ -62,6 +63,7 @@ func mmap_trampoline()
//go:cgo_unsafe_args
func munmap(addr unsafe.Pointer, n uintptr) {
libcCall(unsafe.Pointer(funcPC(munmap_trampoline)), unsafe.Pointer(&addr))
KeepAlive(addr) // Just for consistency. Hopefully addr is not a Go address.
}
func munmap_trampoline()
@@ -69,13 +71,16 @@ func munmap_trampoline()
//go:cgo_unsafe_args
func madvise(addr unsafe.Pointer, n uintptr, flags int32) {
libcCall(unsafe.Pointer(funcPC(madvise_trampoline)), unsafe.Pointer(&addr))
KeepAlive(addr) // Just for consistency. Hopefully addr is not a Go address.
}
func madvise_trampoline()
//go:nosplit
//go:cgo_unsafe_args
func open(name *byte, mode, perm int32) (ret int32) {
return libcCall(unsafe.Pointer(funcPC(open_trampoline)), unsafe.Pointer(&name))
ret = libcCall(unsafe.Pointer(funcPC(open_trampoline)), unsafe.Pointer(&name))
KeepAlive(name)
return
}
func open_trampoline()
@@ -89,14 +94,18 @@ func close_trampoline()
//go:nosplit
//go:cgo_unsafe_args
func read(fd int32, p unsafe.Pointer, n int32) int32 {
return libcCall(unsafe.Pointer(funcPC(read_trampoline)), unsafe.Pointer(&fd))
ret := libcCall(unsafe.Pointer(funcPC(read_trampoline)), unsafe.Pointer(&fd))
KeepAlive(p)
return ret
}
func read_trampoline()
//go:nosplit
//go:cgo_unsafe_args
func write1(fd uintptr, p unsafe.Pointer, n int32) int32 {
return libcCall(unsafe.Pointer(funcPC(write_trampoline)), unsafe.Pointer(&fd))
ret := libcCall(unsafe.Pointer(funcPC(write_trampoline)), unsafe.Pointer(&fd))
KeepAlive(p)
return ret
}
func write_trampoline()
@@ -119,6 +128,8 @@ func pipe2_trampoline()
//go:cgo_unsafe_args
func setitimer(mode int32, new, old *itimerval) {
libcCall(unsafe.Pointer(funcPC(setitimer_trampoline)), unsafe.Pointer(&mode))
KeepAlive(new)
KeepAlive(old)
}
func setitimer_trampoline()
@@ -138,7 +149,12 @@ func usleep_no_g(usec uint32) {
//go:nosplit
//go:cgo_unsafe_args
func sysctl(mib *uint32, miblen uint32, out *byte, size *uintptr, dst *byte, ndst uintptr) int32 {
return libcCall(unsafe.Pointer(funcPC(sysctl_trampoline)), unsafe.Pointer(&mib))
ret := libcCall(unsafe.Pointer(funcPC(sysctl_trampoline)), unsafe.Pointer(&mib))
KeepAlive(mib)
KeepAlive(out)
KeepAlive(size)
KeepAlive(dst)
return ret
}
func sysctl_trampoline()
@@ -182,7 +198,11 @@ func kqueue_trampoline()
//go:nosplit
//go:cgo_unsafe_args
func kevent(kq int32, ch *keventt, nch int32, ev *keventt, nev int32, ts *timespec) int32 {
return libcCall(unsafe.Pointer(funcPC(kevent_trampoline)), unsafe.Pointer(&kq))
ret := libcCall(unsafe.Pointer(funcPC(kevent_trampoline)), unsafe.Pointer(&kq))
KeepAlive(ch)
KeepAlive(ev)
KeepAlive(ts)
return ret
}
func kevent_trampoline()
@@ -190,6 +210,8 @@ func kevent_trampoline()
//go:cgo_unsafe_args
func sigaction(sig uint32, new *sigactiont, old *sigactiont) {
libcCall(unsafe.Pointer(funcPC(sigaction_trampoline)), unsafe.Pointer(&sig))
KeepAlive(new)
KeepAlive(old)
}
func sigaction_trampoline()
@@ -197,6 +219,8 @@ func sigaction_trampoline()
//go:cgo_unsafe_args
func sigprocmask(how uint32, new *sigset, old *sigset) {
libcCall(unsafe.Pointer(funcPC(sigprocmask_trampoline)), unsafe.Pointer(&how))
KeepAlive(new)
KeepAlive(old)
}
func sigprocmask_trampoline()
@@ -204,6 +228,8 @@ func sigprocmask_trampoline()
//go:cgo_unsafe_args
func sigaltstack(new *stackt, old *stackt) {
libcCall(unsafe.Pointer(funcPC(sigaltstack_trampoline)), unsafe.Pointer(&new))
KeepAlive(new)
KeepAlive(old)
}
func sigaltstack_trampoline()

View File

@@ -94,7 +94,7 @@ TEXT runtime·walltime(SB),NOSPLIT,$8-12
MOVQ 0(SP), AX
// generated code for
// func f(x uint64) (uint64, uint64) { return x/1000000000, x%100000000 }
// func f(x uint64) (uint64, uint64) { return x/1000000000, x%1000000000 }
// adapted to reduce duplication
MOVQ AX, CX
MOVQ $1360296554856532783, AX

View File

@@ -348,16 +348,9 @@ TEXT runtime·nanotime1(SB),NOSPLIT,$0-8
CMPB runtime·useQPCTime(SB), $0
JNE useQPC
MOVQ $_INTERRUPT_TIME, DI
loop:
MOVL time_hi1(DI), AX
MOVL time_lo(DI), BX
MOVL time_hi2(DI), CX
CMPL AX, CX
JNE loop
SHLQ $32, CX
ORQ BX, CX
IMULQ $100, CX
MOVQ CX, ret+0(FP)
MOVQ time_lo(DI), AX
IMULQ $100, AX
MOVQ AX, ret+0(FP)
RET
useQPC:
JMP runtime·nanotimeQPC(SB)

View File

@@ -350,7 +350,9 @@ TEXT runtime·nanotime1(SB),NOSPLIT|NOFRAME,$0-8
MOVW $_INTERRUPT_TIME, R3
loop:
MOVW time_hi1(R3), R1
DMB MB_ISH
MOVW time_lo(R3), R0
DMB MB_ISH
MOVW time_hi2(R3), R2
CMP R1, R2
BNE loop

View File

@@ -415,15 +415,7 @@ TEXT runtime·nanotime1(SB),NOSPLIT|NOFRAME,$0-8
CMP $0, R0
BNE useQPC
MOVD $_INTERRUPT_TIME, R3
loop:
MOVWU time_hi1(R3), R1
MOVWU time_lo(R3), R0
MOVWU time_hi2(R3), R2
CMP R1, R2
BNE loop
// wintime = R1:R0, multiply by 100
ORR R1<<32, R0
MOVD time_lo(R3), R0
MOVD $100, R1
MUL R1, R0
MOVD R0, ret+0(FP)

View File

@@ -303,6 +303,8 @@ func syscall_wait4(pid uintptr, wstatus *uint32, options uintptr, rusage unsafe.
entersyscallblock()
asmcgocall(unsafe.Pointer(&asmsysvicall6x), unsafe.Pointer(&call))
exitsyscall()
KeepAlive(wstatus)
KeepAlive(rusage)
return int(call.r1), call.err
}

View File

@@ -422,6 +422,8 @@ func syscall_loadsystemlibrary(filename *uint16, absoluteFilepath *uint16) (hand
}
cgocall(asmstdcallAddr, unsafe.Pointer(c))
KeepAlive(filename)
KeepAlive(absoluteFilepath)
handle = c.r1
if handle == 0 {
err = c.err
@@ -441,6 +443,7 @@ func syscall_loadlibrary(filename *uint16) (handle, err uintptr) {
c.n = 1
c.args = uintptr(noescape(unsafe.Pointer(&filename)))
cgocall(asmstdcallAddr, unsafe.Pointer(c))
KeepAlive(filename)
handle = c.r1
if handle == 0 {
err = c.err
@@ -459,6 +462,7 @@ func syscall_getprocaddress(handle uintptr, procname *byte) (outhandle, err uint
c.n = 2
c.args = uintptr(noescape(unsafe.Pointer(&handle)))
cgocall(asmstdcallAddr, unsafe.Pointer(c))
KeepAlive(procname)
outhandle = c.r1
if outhandle == 0 {
err = c.err

View File

@@ -366,9 +366,9 @@ func deltimer(t *timer) bool {
// dodeltimer removes timer i from the current P's heap.
// We are locked on the P when this is called.
// It reports whether it saw no problems due to races.
// It returns the smallest changed index in pp.timers.
// The caller must have locked the timers for pp.
func dodeltimer(pp *p, i int) {
func dodeltimer(pp *p, i int) int {
if t := pp.timers[i]; t.pp.ptr() != pp {
throw("dodeltimer: wrong P")
} else {
@@ -380,16 +380,18 @@ func dodeltimer(pp *p, i int) {
}
pp.timers[last] = nil
pp.timers = pp.timers[:last]
smallestChanged := i
if i != last {
// Moving to i may have moved the last timer to a new parent,
// so sift up to preserve the heap guarantee.
siftupTimer(pp.timers, i)
smallestChanged = siftupTimer(pp.timers, i)
siftdownTimer(pp.timers, i)
}
if i == 0 {
updateTimer0When(pp)
}
atomic.Xadd(&pp.numTimers, -1)
return smallestChanged
}
// dodeltimer0 removes timer 0 from the current P's heap.
@@ -674,13 +676,14 @@ func adjusttimers(pp *p, now int64) {
switch s := atomic.Load(&t.status); s {
case timerDeleted:
if atomic.Cas(&t.status, s, timerRemoving) {
dodeltimer(pp, i)
changed := dodeltimer(pp, i)
if !atomic.Cas(&t.status, timerRemoving, timerRemoved) {
badTimer()
}
atomic.Xadd(&pp.deletedTimers, -1)
// Look at this heap position again.
i--
// Go back to the earliest changed heap entry.
// "- 1" because the loop will add 1.
i = changed - 1
}
case timerModifiedEarlier, timerModifiedLater:
if atomic.Cas(&t.status, s, timerMoving) {
@@ -690,10 +693,11 @@ func adjusttimers(pp *p, now int64) {
// We don't add it back yet because the
// heap manipulation could cause our
// loop to skip some other timer.
dodeltimer(pp, i)
changed := dodeltimer(pp, i)
moved = append(moved, t)
// Look at this heap position again.
i--
// Go back to the earliest changed heap entry.
// "- 1" because the loop will add 1.
i = changed - 1
}
case timerNoStatus, timerRunning, timerRemoving, timerRemoved, timerMoving:
badTimer()
@@ -1043,7 +1047,10 @@ func timeSleepUntil() (int64, *p) {
// "panic holding locks" message. Instead, we panic while not
// holding a lock.
func siftupTimer(t []*timer, i int) {
// siftupTimer puts the timer at position i in the right place
// in the heap by moving it up toward the top of the heap.
// It returns the smallest changed index.
func siftupTimer(t []*timer, i int) int {
if i >= len(t) {
badTimer()
}
@@ -1063,8 +1070,11 @@ func siftupTimer(t []*timer, i int) {
if tmp != t[i] {
t[i] = tmp
}
return i
}
// siftdownTimer puts the timer at position i in the right place
// in the heap by moving it down toward the bottom of the heap.
func siftdownTimer(t []*timer, i int) {
n := len(t)
if i >= n {

View File

@@ -9,6 +9,7 @@
// http://web.archive.org/web/20210411000829/https://wrkhpi.wordpress.com/2007/08/09/getting-os-information-the-kuser_shared_data-structure/
// Must read hi1, then lo, then hi2. The snapshot is valid if hi1 == hi2.
// Or, on 64-bit, just read lo:hi1 all at once atomically.
#define _INTERRUPT_TIME 0x7ffe0008
#define _SYSTEM_TIME 0x7ffe0014
#define time_lo 0

View File

@@ -12,33 +12,20 @@
TEXT time·now(SB),NOSPLIT,$0-24
CMPB runtime·useQPCTime(SB), $0
JNE useQPC
MOVQ $_INTERRUPT_TIME, DI
loop:
MOVL time_hi1(DI), AX
MOVL time_lo(DI), BX
MOVL time_hi2(DI), CX
CMPL AX, CX
JNE loop
SHLQ $32, AX
ORQ BX, AX
MOVQ time_lo(DI), AX
IMULQ $100, AX
MOVQ AX, mono+16(FP)
MOVQ $_SYSTEM_TIME, DI
wall:
MOVL time_hi1(DI), AX
MOVL time_lo(DI), BX
MOVL time_hi2(DI), CX
CMPL AX, CX
JNE wall
SHLQ $32, AX
ORQ BX, AX
MOVQ time_lo(DI), AX
MOVQ $116444736000000000, DI
SUBQ DI, AX
IMULQ $100, AX
// generated code for
// func f(x uint64) (uint64, uint64) { return x/1000000000, x%100000000 }
// func f(x uint64) (uint64, uint64) { return x/1000000000, x%1000000000 }
// adapted to reduce duplication
MOVQ AX, CX
MOVQ $1360296554856532783, AX

View File

@@ -17,7 +17,9 @@ TEXT time·now(SB),NOSPLIT|NOFRAME,$0-20
MOVW $_INTERRUPT_TIME, R3
loop:
MOVW time_hi1(R3), R1
DMB MB_ISH
MOVW time_lo(R3), R0
DMB MB_ISH
MOVW time_hi2(R3), R2
CMP R1, R2
BNE loop
@@ -34,7 +36,9 @@ loop:
MOVW $_SYSTEM_TIME, R3
wall:
MOVW time_hi1(R3), R1
DMB MB_ISH
MOVW time_lo(R3), R0
DMB MB_ISH
MOVW time_hi2(R3), R2
CMP R1, R2
BNE wall

View File

@@ -13,34 +13,18 @@ TEXT time·now(SB),NOSPLIT|NOFRAME,$0-24
MOVB runtime·useQPCTime(SB), R0
CMP $0, R0
BNE useQPC
MOVD $_INTERRUPT_TIME, R3
loop:
MOVWU time_hi1(R3), R1
MOVWU time_lo(R3), R0
MOVWU time_hi2(R3), R2
CMP R1, R2
BNE loop
// wintime = R1:R0, multiply by 100
ORR R1<<32, R0
MOVD $_INTERRUPT_TIME, R3
MOVD time_lo(R3), R0
MOVD $100, R1
MUL R1, R0
MOVD R0, mono+16(FP)
MOVD $_SYSTEM_TIME, R3
wall:
MOVWU time_hi1(R3), R1
MOVWU time_lo(R3), R0
MOVWU time_hi2(R3), R2
CMP R1, R2
BNE wall
// w = R1:R0 in 100ns units
MOVD time_lo(R3), R0
// convert to Unix epoch (but still 100ns units)
#define delta 116444736000000000
ORR R1<<32, R0
SUB $delta, R0
// Convert to nSec
MOVD $100, R1
MUL R1, R0
@@ -48,17 +32,14 @@ wall:
// Code stolen from compiler output for:
//
// var x uint64
// func f() (sec uint64, nsec uint32) { return x / 1000000000, uint32(x % 100000000) }
// func f() (sec uint64, nsec uint32) { return x / 1000000000, uint32(x % 1000000000) }
//
LSR $1, R0, R1
MOVD $-8543223759426509416, R2
UMULH R2, R1, R1
UMULH R1, R2, R1
LSR $28, R1, R1
MOVD R1, sec+0(FP)
MOVD $-6067343680855748867, R1
UMULH R0, R1, R1
LSR $26, R1, R1
MOVD $100000000, R2
MOVD $1000000000, R2
MSUB R1, R0, R2, R0
MOVW R0, nsec+8(FP)
RET

View File

@@ -126,7 +126,7 @@ func (v *Value) Swap(new interface{}) (old interface{}) {
}
}
// CompareAndSwapPointer executes the compare-and-swap operation for the Value.
// CompareAndSwap executes the compare-and-swap operation for the Value.
//
// All calls to CompareAndSwap for a given Value must use values of the same
// concrete type. CompareAndSwap of an inconsistent type panics, as does

View File

@@ -153,9 +153,6 @@ func forkExec(argv0 string, argv []string, attr *ProcAttr) (pid int, err error)
sys = &zeroSysProcAttr
}
p[0] = -1
p[1] = -1
// Convert args to C form.
argv0p, err := BytePtrFromString(argv0)
if err != nil {
@@ -205,14 +202,17 @@ func forkExec(argv0 string, argv []string, attr *ProcAttr) (pid int, err error)
// Allocate child status pipe close on exec.
if err = forkExecPipe(p[:]); err != nil {
goto error
ForkLock.Unlock()
return 0, err
}
// Kick off child.
pid, err1 = forkAndExecInChild(argv0p, argvp, envvp, chroot, dir, attr, sys, p[1])
if err1 != 0 {
err = Errno(err1)
goto error
Close(p[0])
Close(p[1])
ForkLock.Unlock()
return 0, Errno(err1)
}
ForkLock.Unlock()
@@ -244,14 +244,6 @@ func forkExec(argv0 string, argv []string, attr *ProcAttr) (pid int, err error)
// Read got EOF, so pipe closed on exec, so exec succeeded.
return pid, nil
error:
if p[0] >= 0 {
Close(p[0])
Close(p[1])
}
ForkLock.Unlock()
return 0, err
}
// Combination of fork and exec, careful to be thread safe.

View File

@@ -390,8 +390,10 @@ func StartProcess(argv0 string, argv []string, attr *ProcAttr) (pid int, handle
}
fd = fd[:j]
willInheritHandles := len(fd) > 0 && !sys.NoInheritHandles
// Do not accidentally inherit more than these handles.
if len(fd) > 0 {
if willInheritHandles {
err = updateProcThreadAttribute(si.ProcThreadAttributeList, 0, _PROC_THREAD_ATTRIBUTE_HANDLE_LIST, unsafe.Pointer(&fd[0]), uintptr(len(fd))*unsafe.Sizeof(fd[0]), nil, nil)
if err != nil {
return 0, 0, err
@@ -401,9 +403,9 @@ func StartProcess(argv0 string, argv []string, attr *ProcAttr) (pid int, handle
pi := new(ProcessInformation)
flags := sys.CreationFlags | CREATE_UNICODE_ENVIRONMENT | _EXTENDED_STARTUPINFO_PRESENT
if sys.Token != 0 {
err = CreateProcessAsUser(sys.Token, argv0p, argvp, sys.ProcessAttributes, sys.ThreadAttributes, len(fd) > 0 && !sys.NoInheritHandles, flags, createEnvBlock(attr.Env), dirp, &si.StartupInfo, pi)
err = CreateProcessAsUser(sys.Token, argv0p, argvp, sys.ProcessAttributes, sys.ThreadAttributes, willInheritHandles, flags, createEnvBlock(attr.Env), dirp, &si.StartupInfo, pi)
} else {
err = CreateProcess(argv0p, argvp, sys.ProcessAttributes, sys.ThreadAttributes, len(fd) > 0 && !sys.NoInheritHandles, flags, createEnvBlock(attr.Env), dirp, &si.StartupInfo, pi)
err = CreateProcess(argv0p, argvp, sys.ProcessAttributes, sys.ThreadAttributes, willInheritHandles, flags, createEnvBlock(attr.Env), dirp, &si.StartupInfo, pi)
}
if err != nil {
return 0, 0, err

View File

@@ -64,8 +64,10 @@ func Pipe(p []int) (err error) {
}
var pp [2]_C_int
err = pipe(&pp)
p[0] = int(pp[0])
p[1] = int(pp[1])
if err == nil {
p[0] = int(pp[0])
p[1] = int(pp[1])
}
return
}

View File

@@ -96,8 +96,10 @@ func Pipe(p []int) (err error) {
}
var q [2]int32
err = pipe(&q)
p[0] = int(q[0])
p[1] = int(q[1])
if err == nil {
p[0] = int(q[0])
p[1] = int(q[1])
}
return
}

View File

@@ -96,8 +96,11 @@ func Pipe(p []int) (err error) {
if len(p) != 2 {
return EINVAL
}
p[0], p[1], err = pipe()
return
r, w, err := pipe()
if err == nil {
p[0], p[1] = r, w
}
return err
}
//sysnb pipe2(p *[2]_C_int, flags int) (r int, w int, err error)
@@ -109,7 +112,10 @@ func Pipe2(p []int, flags int) (err error) {
var pp [2]_C_int
// pipe2 on dragonfly takes an fds array as an argument, but still
// returns the file descriptors.
p[0], p[1], err = pipe2(&pp, flags)
r, w, err := pipe2(&pp, flags)
if err == nil {
p[0], p[1] = r, w
}
return err
}

View File

@@ -105,8 +105,10 @@ func Pipe2(p []int, flags int) error {
}
var pp [2]_C_int
err := pipe2(&pp, flags)
p[0] = int(pp[0])
p[1] = int(pp[1])
if err == nil {
p[0] = int(pp[0])
p[1] = int(pp[1])
}
return err
}

View File

@@ -30,8 +30,10 @@ func Pipe(p []int) (err error) {
}
var pp [2]_C_int
err = pipe(&pp)
p[0] = int(pp[0])
p[1] = int(pp[1])
if err == nil {
p[0] = int(pp[0])
p[1] = int(pp[1])
}
return
}
@@ -43,8 +45,10 @@ func Pipe2(p []int, flags int) (err error) {
}
var pp [2]_C_int
err = pipe2(&pp, flags)
p[0] = int(pp[0])
p[1] = int(pp[1])
if err == nil {
p[0] = int(pp[0])
p[1] = int(pp[1])
}
return
}

View File

@@ -118,8 +118,10 @@ func Pipe(p []int) (err error) {
}
var pp [2]_C_int
err = pipe(&pp)
p[0] = int(pp[0])
p[1] = int(pp[1])
if err == nil {
p[0] = int(pp[0])
p[1] = int(pp[1])
}
return
}
@@ -131,8 +133,10 @@ func Pipe2(p []int, flags int) (err error) {
}
var pp [2]_C_int
err = pipe2(&pp, flags)
p[0] = int(pp[0])
p[1] = int(pp[1])
if err == nil {
p[0] = int(pp[0])
p[1] = int(pp[1])
}
return
}

View File

@@ -34,8 +34,10 @@ func Pipe(p []int) (err error) {
if err == ENOSYS {
err = pipe(&pp)
}
p[0] = int(pp[0])
p[1] = int(pp[1])
if err == nil {
p[0] = int(pp[0])
p[1] = int(pp[1])
}
return
}
@@ -47,8 +49,10 @@ func Pipe2(p []int, flags int) (err error) {
}
var pp [2]_C_int
err = pipe2(&pp, flags)
p[0] = int(pp[0])
p[1] = int(pp[1])
if err == nil {
p[0] = int(pp[0])
p[1] = int(pp[1])
}
return
}

View File

@@ -152,8 +152,10 @@ func Pipe(p []int) (err error) {
}
var pp [2]_C_int
err = pipe2(&pp, 0)
p[0] = int(pp[0])
p[1] = int(pp[1])
if err == nil {
p[0] = int(pp[0])
p[1] = int(pp[1])
}
return
}
@@ -165,8 +167,10 @@ func Pipe2(p []int, flags int) (err error) {
}
var pp [2]_C_int
err = pipe2(&pp, flags)
p[0] = int(pp[0])
p[1] = int(pp[1])
if err == nil {
p[0] = int(pp[0])
p[1] = int(pp[1])
}
return
}

View File

@@ -109,8 +109,10 @@ func Pipe(p []int) (err error) {
}
var pp [2]_C_int
err = pipe2(&pp, 0)
p[0] = int(pp[0])
p[1] = int(pp[1])
if err == nil {
p[0] = int(pp[0])
p[1] = int(pp[1])
}
return
}
@@ -122,8 +124,10 @@ func Pipe2(p []int, flags int) (err error) {
}
var pp [2]_C_int
err = pipe2(&pp, flags)
p[0] = int(pp[0])
p[1] = int(pp[1])
if err == nil {
p[0] = int(pp[0])
p[1] = int(pp[1])
}
return
}

View File

@@ -120,8 +120,10 @@ func Pipe2(p []int, flags int) (err error) {
}
var pp [2]_C_int
err = pipe2(&pp, flags)
p[0] = int(pp[0])
p[1] = int(pp[1])
if err == nil {
p[0] = int(pp[0])
p[1] = int(pp[1])
}
return
}
@@ -131,8 +133,11 @@ func Pipe(p []int) (err error) {
if len(p) != 2 {
return EINVAL
}
p[0], p[1], err = pipe()
return
r, w, err := pipe()
if err == nil {
p[0], p[1] = r, w
}
return err
}
//sys mmap2(addr uintptr, length uintptr, prot int, flags int, fd int, pageOffset uintptr) (xaddr uintptr, err error)

View File

@@ -88,8 +88,10 @@ func Pipe(p []int) (err error) {
}
var pp [2]_C_int
err = pipe2(&pp, 0)
p[0] = int(pp[0])
p[1] = int(pp[1])
if err == nil {
p[0] = int(pp[0])
p[1] = int(pp[1])
}
return
}
@@ -101,8 +103,10 @@ func Pipe2(p []int, flags int) (err error) {
}
var pp [2]_C_int
err = pipe2(&pp, flags)
p[0] = int(pp[0])
p[1] = int(pp[1])
if err == nil {
p[0] = int(pp[0])
p[1] = int(pp[1])
}
return
}

View File

@@ -155,8 +155,10 @@ func Pipe(p []int) (err error) {
}
var pp [2]_C_int
err = pipe2(&pp, 0)
p[0] = int(pp[0])
p[1] = int(pp[1])
if err == nil {
p[0] = int(pp[0])
p[1] = int(pp[1])
}
return
}
@@ -168,8 +170,10 @@ func Pipe2(p []int, flags int) (err error) {
}
var pp [2]_C_int
err = pipe2(&pp, flags)
p[0] = int(pp[0])
p[1] = int(pp[1])
if err == nil {
p[0] = int(pp[0])
p[1] = int(pp[1])
}
return
}

View File

@@ -80,8 +80,10 @@ func Pipe(p []int) (err error) {
}
var pp [2]_C_int
err = pipe2(&pp, 0)
p[0] = int(pp[0])
p[1] = int(pp[1])
if err == nil {
p[0] = int(pp[0])
p[1] = int(pp[1])
}
return
}
@@ -93,8 +95,10 @@ func Pipe2(p []int, flags int) (err error) {
}
var pp [2]_C_int
err = pipe2(&pp, flags)
p[0] = int(pp[0])
p[1] = int(pp[1])
if err == nil {
p[0] = int(pp[0])
p[1] = int(pp[1])
}
return
}

View File

@@ -112,8 +112,10 @@ func Pipe2(p []int, flags int) error {
}
var pp [2]_C_int
err := pipe2(&pp, flags)
p[0] = int(pp[0])
p[1] = int(pp[1])
if err == nil {
p[0] = int(pp[0])
p[1] = int(pp[1])
}
return err
}

View File

@@ -72,8 +72,10 @@ func Pipe2(p []int, flags int) error {
}
var pp [2]_C_int
err := pipe2(&pp, flags)
p[0] = int(pp[0])
p[1] = int(pp[1])
if err == nil {
p[0] = int(pp[0])
p[1] = int(pp[1])
}
return err
}

View File

@@ -198,8 +198,10 @@ func Pipe(p []int) (err error) {
}
var pp [2]int32
err = pipe(&pp)
p[0] = int(pp[0])
p[1] = int(pp[1])
if err == nil {
p[0] = int(pp[0])
p[1] = int(pp[1])
}
return
}

View File

@@ -55,7 +55,9 @@ func Pipe(p []int) (err error) {
if e1 != 0 {
err = Errno(e1)
}
p[0], p[1] = int(r0), int(w0)
if err == nil {
p[0], p[1] = int(r0), int(w0)
}
return
}

Some files were not shown because too many files have changed in this diff Show More