From cef4d1953dac766c4166cb5fd6b069b99801ee7c Mon Sep 17 00:00:00 2001
From: chenjiankun
Date: Fri, 18 Jun 2021 15:46:44 +0800
Subject: [PATCH] batch synchronization
---
0001-drop-hard-code-cert.patch | 135 ++
...o1.15-doc-go1.15-mention-1.15.3-cgo-.patch | 52 +
...o1.15-cmd-go-fix-mod_get_fallback-te.patch | 38 +
...o1.15-internal-execabs-only-run-test.patch | 54 +
...o1.15-cmd-compile-don-t-short-circui.patch | 154 ++
...o1.15-cmd-go-fix-get_update_unknown_.patch | 47 +
...o1.15-net-http-update-bundled-x-net-.patch | 106 ++
...o1.15-cmd-go-don-t-lookup-the-path-f.patch | 208 +++
...o1.15-cmd-link-internal-ld-pe-fix-se.patch | 58 +
...o1.15-cmd-internal-goobj2-fix-buglet.patch | 73 +
...o1.15-runtime-don-t-adjust-timer-pp-.patch | 72 +
...o1.15-runtime-cgo-fix-Android-build-.patch | 82 ++
...o1.15-internal-poll-if-copy_file_ran.patch | 102 ++
...o1.15-internal-poll-netpollcheckerr-.patch | 166 +++
...o1.15-cmd-compile-do-not-assume-TST-.patch | 1281 +++++++++++++++++
...o1.15-syscall-do-not-overflow-key-me.patch | 115 ++
...o1.15-time-correct-unusual-extension.patch | 150 ++
...o1.15-cmd-compile-fix-escape-analysi.patch | 87 ++
...o1.15-net-http-ignore-connection-clo.patch | 124 ++
...o1.15-net-http-add-connections-back-.patch | 129 ++
...o1.15-security-encoding-xml-prevent-.patch | 6 +-
...o1.15-cmd-go-don-t-report-missing-st.patch | 121 ++
...o1.15-cmd-go-internal-modfetch-detec.patch | 310 ++++
...o1.15-cmd-link-generate-trampoline-f.patch | 133 ++
...o1.15-net-http-update-bundled-x-net-.patch | 49 +
...o1.15-net-http-fix-detection-of-Roun.patch | 81 ++
...o1.15-build-set-GOPATH-consistently-.patch | 105 ++
...o1.15-database-sql-fix-tx-stmt-deadl.patch | 134 ++
...o1.15-cmd-compile-disable-shortcircu.patch | 107 ++
...o1.15-runtime-non-strict-InlTreeInde.patch | 157 ++
...o1.15-cmd-cgo-avoid-exporting-all-sy.patch | 172 +++
...o1.15-cmd-link-avoid-exporting-all-s.patch | 188 +++
...o1.15-cmd-cgo-remove-unnecessary-spa.patch | 60 +
...o1.15-time-use-offset-and-isDST-when.patch | 355 +++++
...o1.15-std-update-golang.org-x-net-to.patch | 97 ++
...o1.15-runtime-time-disable-preemptio.patch | 95 ++
...o1.15-runtime-non-strict-InlTreeInde.patch | 54 +
...o1.15-runtime-pprof-skip-tests-for-A.patch | 48 +
...o1.15-math-big-fix-TestShiftOverlap-.patch | 65 +
...o1.15-math-big-remove-the-s390x-asse.patch | 337 +++++
...-fix-hijack-hang-at-abortPendingRead.patch | 59 +
golang.spec | 48 +-
42 files changed, 6012 insertions(+), 2 deletions(-)
create mode 100644 0001-drop-hard-code-cert.patch
create mode 100644 0001-release-branch.go1.15-doc-go1.15-mention-1.15.3-cgo-.patch
create mode 100644 0002-release-branch.go1.15-cmd-go-fix-mod_get_fallback-te.patch
create mode 100644 0003-release-branch.go1.15-internal-execabs-only-run-test.patch
create mode 100644 0004-release-branch.go1.15-cmd-compile-don-t-short-circui.patch
create mode 100644 0005-release-branch.go1.15-cmd-go-fix-get_update_unknown_.patch
create mode 100644 0006-release-branch.go1.15-net-http-update-bundled-x-net-.patch
create mode 100644 0007-release-branch.go1.15-cmd-go-don-t-lookup-the-path-f.patch
create mode 100644 0008-release-branch.go1.15-cmd-link-internal-ld-pe-fix-se.patch
create mode 100644 0009-release-branch.go1.15-cmd-internal-goobj2-fix-buglet.patch
create mode 100644 0010-release-branch.go1.15-runtime-don-t-adjust-timer-pp-.patch
create mode 100644 0011-release-branch.go1.15-runtime-cgo-fix-Android-build-.patch
create mode 100644 0013-release-branch.go1.15-internal-poll-if-copy_file_ran.patch
create mode 100644 0014-release-branch.go1.15-internal-poll-netpollcheckerr-.patch
create mode 100644 0015-release-branch.go1.15-cmd-compile-do-not-assume-TST-.patch
create mode 100644 0016-release-branch.go1.15-syscall-do-not-overflow-key-me.patch
create mode 100644 0017-release-branch.go1.15-time-correct-unusual-extension.patch
create mode 100644 0018-release-branch.go1.15-cmd-compile-fix-escape-analysi.patch
create mode 100644 0019-release-branch.go1.15-net-http-ignore-connection-clo.patch
create mode 100644 0020-release-branch.go1.15-net-http-add-connections-back-.patch
rename 0001-release-branch.go1.15-security-encoding-xml-prevent-.patch => 0021-release-branch.go1.15-security-encoding-xml-prevent-.patch (96%)
create mode 100644 0023-release-branch.go1.15-cmd-go-don-t-report-missing-st.patch
create mode 100644 0025-release-branch.go1.15-cmd-go-internal-modfetch-detec.patch
create mode 100644 0026-release-branch.go1.15-cmd-link-generate-trampoline-f.patch
create mode 100644 0027-release-branch.go1.15-net-http-update-bundled-x-net-.patch
create mode 100644 0028-release-branch.go1.15-net-http-fix-detection-of-Roun.patch
create mode 100644 0029-release-branch.go1.15-build-set-GOPATH-consistently-.patch
create mode 100644 0030-release-branch.go1.15-database-sql-fix-tx-stmt-deadl.patch
create mode 100644 0031-release-branch.go1.15-cmd-compile-disable-shortcircu.patch
create mode 100644 0032-release-branch.go1.15-runtime-non-strict-InlTreeInde.patch
create mode 100644 0033-release-branch.go1.15-cmd-cgo-avoid-exporting-all-sy.patch
create mode 100644 0034-release-branch.go1.15-cmd-link-avoid-exporting-all-s.patch
create mode 100644 0035-release-branch.go1.15-cmd-cgo-remove-unnecessary-spa.patch
create mode 100644 0037-release-branch.go1.15-time-use-offset-and-isDST-when.patch
create mode 100644 0038-release-branch.go1.15-std-update-golang.org-x-net-to.patch
create mode 100644 0039-release-branch.go1.15-runtime-time-disable-preemptio.patch
create mode 100644 0040-release-branch.go1.15-runtime-non-strict-InlTreeInde.patch
create mode 100644 0041-release-branch.go1.15-runtime-pprof-skip-tests-for-A.patch
create mode 100644 0043-release-branch.go1.15-math-big-fix-TestShiftOverlap-.patch
create mode 100644 0044-release-branch.go1.15-math-big-remove-the-s390x-asse.patch
create mode 100644 0045-net-http-fix-hijack-hang-at-abortPendingRead.patch
diff --git a/0001-drop-hard-code-cert.patch b/0001-drop-hard-code-cert.patch
new file mode 100644
index 0000000..1af1acc
--- /dev/null
+++ b/0001-drop-hard-code-cert.patch
@@ -0,0 +1,135 @@
+From 2720067ebfb7568792bb0c8fe3fbf095c89b77a9 Mon Sep 17 00:00:00 2001
+From: jingrui
+Date: Tue, 17 Mar 2020 17:43:33 +0800
+Subject: [PATCH] drop hard-code cert
+
+Signed-off-by: jingrui
+---
+ src/crypto/x509/test-file.crt | 32 ---------------------------
+ src/crypto/x509/testdata/test-dir.crt | 31 --------------------------
+ src/net/http/internal/testcert.go | 31 ++------------------------
+ 3 files changed, 2 insertions(+), 92 deletions(-)
+ delete mode 100644 src/crypto/x509/test-file.crt
+ delete mode 100644 src/crypto/x509/testdata/test-dir.crt
+
+diff --git a/src/crypto/x509/test-file.crt b/src/crypto/x509/test-file.crt
+deleted file mode 100644
+index caa83b9..0000000
+--- a/src/crypto/x509/test-file.crt
++++ /dev/null
+@@ -1,32 +0,0 @@
+------BEGIN CERTIFICATE-----
+-MIIFbTCCA1WgAwIBAgIJAN338vEmMtLsMA0GCSqGSIb3DQEBCwUAME0xCzAJBgNV
+-BAYTAlVLMRMwEQYDVQQIDApUZXN0LVN0YXRlMRUwEwYDVQQKDAxHb2xhbmcgVGVz
+-dHMxEjAQBgNVBAMMCXRlc3QtZmlsZTAeFw0xNzAyMDEyMzUyMDhaFw0yNzAxMzAy
+-MzUyMDhaME0xCzAJBgNVBAYTAlVLMRMwEQYDVQQIDApUZXN0LVN0YXRlMRUwEwYD
+-VQQKDAxHb2xhbmcgVGVzdHMxEjAQBgNVBAMMCXRlc3QtZmlsZTCCAiIwDQYJKoZI
+-hvcNAQEBBQADggIPADCCAgoCggIBAPMGiLjdiffQo3Xc8oUe7wsDhSaAJFOhO6Qs
+-i0xYrYl7jmCuz9rGD2fdgk5cLqGazKuQ6fIFzHXFU2BKs4CWXt9KO0KFEhfvZeuW
+-jG5d7C1ZUiuKOrPqjKVu8SZtFPc7y7Ke7msXzY+Z2LLyiJJ93LCMq4+cTSGNXVlI
+-KqUxhxeoD5/QkUPyQy/ilu3GMYfx/YORhDP6Edcuskfj8wRh1UxBejP8YPMvI6St
+-cE2GkxoEGqDWnQ/61F18te6WI3MD29tnKXOkXVhnSC+yvRLljotW2/tAhHKBG4tj
+-iQWT5Ri4Wrw2tXxPKRLsVWc7e1/hdxhnuvYpXkWNhKsm002jzkFXlzfEwPd8nZdw
+-5aT6gPUBN2AAzdoqZI7E200i0orEF7WaSoMfjU1tbHvExp3vyAPOfJ5PS2MQ6W03
+-Zsy5dTVH+OBH++rkRzQCFcnIv/OIhya5XZ9KX9nFPgBEP7Xq2A+IjH7B6VN/S/bv
+-8lhp2V+SQvlew9GttKC4hKuPsl5o7+CMbcqcNUdxm9gGkN8epGEKCuix97bpNlxN
+-fHZxHE5+8GMzPXMkCD56y5TNKR6ut7JGHMPtGl5lPCLqzG/HzYyFgxsDfDUu2B0A
+-GKj0lGpnLfGqwhs2/s3jpY7+pcvVQxEpvVTId5byDxu1ujP4HjO/VTQ2P72rE8Ft
+-C6J2Av0tAgMBAAGjUDBOMB0GA1UdDgQWBBTLT/RbyfBB/Pa07oBnaM+QSJPO9TAf
+-BgNVHSMEGDAWgBTLT/RbyfBB/Pa07oBnaM+QSJPO9TAMBgNVHRMEBTADAQH/MA0G
+-CSqGSIb3DQEBCwUAA4ICAQB3sCntCcQwhMgRPPyvOCMyTcQ/Iv+cpfxz2Ck14nlx
+-AkEAH2CH0ov5GWTt07/ur3aa5x+SAKi0J3wTD1cdiw4U/6Uin6jWGKKxvoo4IaeK
+-SbM8w/6eKx6UbmHx7PA/eRABY9tTlpdPCVgw7/o3WDr03QM+IAtatzvaCPPczake
+-pbdLwmBZB/v8V+6jUajy6jOgdSH0PyffGnt7MWgDETmNC6p/Xigp5eh+C8Fb4NGT
+-xgHES5PBC+sruWp4u22bJGDKTvYNdZHsnw/CaKQWNsQqwisxa3/8N5v+PCff/pxl
+-r05pE3PdHn9JrCl4iWdVlgtiI9BoPtQyDfa/OEFaScE8KYR8LxaAgdgp3zYncWls
+-BpwQ6Y/A2wIkhlD9eEp5Ib2hz7isXOs9UwjdriKqrBXqcIAE5M+YIk3+KAQKxAtd
+-4YsK3CSJ010uphr12YKqlScj4vuKFjuOtd5RyyMIxUG3lrrhAu2AzCeKCLdVgA8+
+-75FrYMApUdvcjp4uzbBoED4XRQlx9kdFHVbYgmE/+yddBYJM8u4YlgAL0hW2/D8p
+-z9JWIfxVmjJnBnXaKGBuiUyZ864A3PJndP6EMMo7TzS2CDnfCYuJjvI0KvDjFNmc
+-rQA04+qfMSEz3nmKhbbZu4eYLzlADhfH8tT4GMtXf71WLA5AUHGf2Y4+HIHTsmHG
+-vQ==
+------END CERTIFICATE-----
+diff --git a/src/crypto/x509/testdata/test-dir.crt b/src/crypto/x509/testdata/test-dir.crt
+deleted file mode 100644
+index b7fc9c5..0000000
+--- a/src/crypto/x509/testdata/test-dir.crt
++++ /dev/null
+@@ -1,31 +0,0 @@
+------BEGIN CERTIFICATE-----
+-MIIFazCCA1OgAwIBAgIJAL8a/lsnspOqMA0GCSqGSIb3DQEBCwUAMEwxCzAJBgNV
+-BAYTAlVLMRMwEQYDVQQIDApUZXN0LVN0YXRlMRUwEwYDVQQKDAxHb2xhbmcgVGVz
+-dHMxETAPBgNVBAMMCHRlc3QtZGlyMB4XDTE3MDIwMTIzNTAyN1oXDTI3MDEzMDIz
+-NTAyN1owTDELMAkGA1UEBhMCVUsxEzARBgNVBAgMClRlc3QtU3RhdGUxFTATBgNV
+-BAoMDEdvbGFuZyBUZXN0czERMA8GA1UEAwwIdGVzdC1kaXIwggIiMA0GCSqGSIb3
+-DQEBAQUAA4ICDwAwggIKAoICAQDzBoi43Yn30KN13PKFHu8LA4UmgCRToTukLItM
+-WK2Je45grs/axg9n3YJOXC6hmsyrkOnyBcx1xVNgSrOAll7fSjtChRIX72Xrloxu
+-XewtWVIrijqz6oylbvEmbRT3O8uynu5rF82Pmdiy8oiSfdywjKuPnE0hjV1ZSCql
+-MYcXqA+f0JFD8kMv4pbtxjGH8f2DkYQz+hHXLrJH4/MEYdVMQXoz/GDzLyOkrXBN
+-hpMaBBqg1p0P+tRdfLXuliNzA9vbZylzpF1YZ0gvsr0S5Y6LVtv7QIRygRuLY4kF
+-k+UYuFq8NrV8TykS7FVnO3tf4XcYZ7r2KV5FjYSrJtNNo85BV5c3xMD3fJ2XcOWk
+-+oD1ATdgAM3aKmSOxNtNItKKxBe1mkqDH41NbWx7xMad78gDznyeT0tjEOltN2bM
+-uXU1R/jgR/vq5Ec0AhXJyL/ziIcmuV2fSl/ZxT4ARD+16tgPiIx+welTf0v27/JY
+-adlfkkL5XsPRrbSguISrj7JeaO/gjG3KnDVHcZvYBpDfHqRhCgrosfe26TZcTXx2
+-cRxOfvBjMz1zJAg+esuUzSkerreyRhzD7RpeZTwi6sxvx82MhYMbA3w1LtgdABio
+-9JRqZy3xqsIbNv7N46WO/qXL1UMRKb1UyHeW8g8btboz+B4zv1U0Nj+9qxPBbQui
+-dgL9LQIDAQABo1AwTjAdBgNVHQ4EFgQUy0/0W8nwQfz2tO6AZ2jPkEiTzvUwHwYD
+-VR0jBBgwFoAUy0/0W8nwQfz2tO6AZ2jPkEiTzvUwDAYDVR0TBAUwAwEB/zANBgkq
+-hkiG9w0BAQsFAAOCAgEAvEVnUYsIOt87rggmLPqEueynkuQ+562M8EDHSQl82zbe
+-xDCxeg3DvPgKb+RvaUdt1362z/szK10SoeMgx6+EQLoV9LiVqXwNqeYfixrhrdw3
+-ppAhYYhymdkbUQCEMHypmXP1vPhAz4o8Bs+eES1M+zO6ErBiD7SqkmBElT+GixJC
+-6epC9ZQFs+dw3lPlbiZSsGE85sqc3VAs0/JgpL/pb1/Eg4s0FUhZD2C2uWdSyZGc
+-g0/v3aXJCp4j/9VoNhI1WXz3M45nysZIL5OQgXymLqJElQa1pZ3Wa4i/nidvT4AT
+-Xlxc/qijM8set/nOqp7hVd5J0uG6qdwLRILUddZ6OpXd7ZNi1EXg+Bpc7ehzGsDt
+-3UFGzYXDjxYnK2frQfjLS8stOQIqSrGthW6x0fdkVx0y8BByvd5J6+JmZl4UZfzA
+-m99VxXSt4B9x6BvnY7ktzcFDOjtuLc4B/7yg9fv1eQuStA4cHGGAttsCg1X/Kx8W
+-PvkkeH0UWDZ9vhH9K36703z89da6MWF+bz92B0+4HoOmlVaXRkvblsNaynJnL0LC
+-Ayry7QBxuh5cMnDdRwJB3AVJIiJ1GVpb7aGvBOnx+s2lwRv9HWtghb+cbwwktx1M
+-JHyBf3GZNSWTpKY7cD8V+NnBv3UuioOVVo+XAU4LF/bYUjdRpxWADJizNtZrtFo=
+------END CERTIFICATE-----
+diff --git a/src/net/http/internal/testcert.go b/src/net/http/internal/testcert.go
+index 2284a83..a33d06b 100644
+--- a/src/net/http/internal/testcert.go
++++ b/src/net/http/internal/testcert.go
+@@ -10,36 +10,9 @@ import "strings"
+ // "127.0.0.1" and "[::1]", expiring at Jan 29 16:00:00 2084 GMT.
+ // generated from src/crypto/tls:
+ // go run generate_cert.go --rsa-bits 1024 --host 127.0.0.1,::1,example.com --ca --start-date "Jan 1 00:00:00 1970" --duration=1000000h
+-var LocalhostCert = []byte(`-----BEGIN CERTIFICATE-----
+-MIICEzCCAXygAwIBAgIQMIMChMLGrR+QvmQvpwAU6zANBgkqhkiG9w0BAQsFADAS
+-MRAwDgYDVQQKEwdBY21lIENvMCAXDTcwMDEwMTAwMDAwMFoYDzIwODQwMTI5MTYw
+-MDAwWjASMRAwDgYDVQQKEwdBY21lIENvMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB
+-iQKBgQDuLnQAI3mDgey3VBzWnB2L39JUU4txjeVE6myuDqkM/uGlfjb9SjY1bIw4
+-iA5sBBZzHi3z0h1YV8QPuxEbi4nW91IJm2gsvvZhIrCHS3l6afab4pZBl2+XsDul
+-rKBxKKtD1rGxlG4LjncdabFn9gvLZad2bSysqz/qTAUStTvqJQIDAQABo2gwZjAO
+-BgNVHQ8BAf8EBAMCAqQwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDwYDVR0TAQH/BAUw
+-AwEB/zAuBgNVHREEJzAlggtleGFtcGxlLmNvbYcEfwAAAYcQAAAAAAAAAAAAAAAA
+-AAAAATANBgkqhkiG9w0BAQsFAAOBgQCEcetwO59EWk7WiJsG4x8SY+UIAA+flUI9
+-tyC4lNhbcF2Idq9greZwbYCqTTTr2XiRNSMLCOjKyI7ukPoPjo16ocHj+P3vZGfs
+-h1fIw3cSS2OolhloGw/XM6RWPWtPAlGykKLciQrBru5NAPvCMsb/I1DAceTiotQM
+-fblo6RBxUQ==
+------END CERTIFICATE-----`)
++var LocalhostCert = []byte(``)
+
+ // LocalhostKey is the private key for localhostCert.
+-var LocalhostKey = []byte(testingKey(`-----BEGIN RSA TESTING KEY-----
+-MIICXgIBAAKBgQDuLnQAI3mDgey3VBzWnB2L39JUU4txjeVE6myuDqkM/uGlfjb9
+-SjY1bIw4iA5sBBZzHi3z0h1YV8QPuxEbi4nW91IJm2gsvvZhIrCHS3l6afab4pZB
+-l2+XsDulrKBxKKtD1rGxlG4LjncdabFn9gvLZad2bSysqz/qTAUStTvqJQIDAQAB
+-AoGAGRzwwir7XvBOAy5tM/uV6e+Zf6anZzus1s1Y1ClbjbE6HXbnWWF/wbZGOpet
+-3Zm4vD6MXc7jpTLryzTQIvVdfQbRc6+MUVeLKwZatTXtdZrhu+Jk7hx0nTPy8Jcb
+-uJqFk541aEw+mMogY/xEcfbWd6IOkp+4xqjlFLBEDytgbIECQQDvH/E6nk+hgN4H
+-qzzVtxxr397vWrjrIgPbJpQvBsafG7b0dA4AFjwVbFLmQcj2PprIMmPcQrooz8vp
+-jy4SHEg1AkEA/v13/5M47K9vCxmb8QeD/asydfsgS5TeuNi8DoUBEmiSJwma7FXY
+-fFUtxuvL7XvjwjN5B30pNEbc6Iuyt7y4MQJBAIt21su4b3sjXNueLKH85Q+phy2U
+-fQtuUE9txblTu14q3N7gHRZB4ZMhFYyDy8CKrN2cPg/Fvyt0Xlp/DoCzjA0CQQDU
+-y2ptGsuSmgUtWj3NM9xuwYPm+Z/F84K6+ARYiZ6PYj013sovGKUFfYAqVXVlxtIX
+-qyUBnu3X9ps8ZfjLZO7BAkEAlT4R5Yl6cGhaJQYZHOde3JEMhNRcVFMO8dJDaFeo
+-f9Oeos0UUothgiDktdQHxdNEwLjQf7lJJBzV+5OtwswCWA==
+------END RSA TESTING KEY-----`))
++var LocalhostKey = []byte(testingKey(``))
+
+ func testingKey(s string) string { return strings.ReplaceAll(s, "TESTING KEY", "PRIVATE KEY") }
+--
+2.17.1
+
diff --git a/0001-release-branch.go1.15-doc-go1.15-mention-1.15.3-cgo-.patch b/0001-release-branch.go1.15-doc-go1.15-mention-1.15.3-cgo-.patch
new file mode 100644
index 0000000..dfe3597
--- /dev/null
+++ b/0001-release-branch.go1.15-doc-go1.15-mention-1.15.3-cgo-.patch
@@ -0,0 +1,52 @@
+From 069f9d96d179becc61231d566c9a75f1ec26e991 Mon Sep 17 00:00:00 2001
+From: Ian Lance Taylor
+Date: Fri, 11 Dec 2020 19:10:00 -0800
+Subject: [PATCH 01/44] [release-branch.go1.15] doc/go1.15: mention 1.15.3 cgo
+ restriction on empty structs
+
+For #40954
+
+Change-Id: I6a30aed31a16e820817f4ca5c7f591222e922946
+Reviewed-on: https://go-review.googlesource.com/c/go/+/277432
+Trust: Ian Lance Taylor
+Reviewed-by: Keith Randall
+(cherry picked from commit 129bb1917b4914f0743ec9b4ef0dfb74df39c07d)
+Reviewed-on: https://go-review.googlesource.com/c/go/+/278573
+Run-TryBot: Ian Lance Taylor
+TryBot-Result: Go Bot
+Reviewed-by: Dmitri Shuralyov
+
+Conflict:NA
+Reference:https://github.com/golang/go/commit/069f9d96d179becc61231d566c9a75f1ec26e991
+
+---
+ doc/go1.15.html | 13 +++++++++++++
+ 1 file changed, 13 insertions(+)
+
+diff --git a/doc/go1.15.html b/doc/go1.15.html
+index c691bf3bd5..c9997c0ca3 100644
+--- a/doc/go1.15.html
++++ b/doc/go1.15.html
+@@ -397,6 +397,19 @@ Do not send CLs removing the interior tags from such phrases.
+ documentation for more information.
+
+
++
++ In Go 1.15.3 and later, cgo will not permit Go code to allocate an
++ undefined struct type (a C struct defined as just struct
++ S;
or similar) on the stack or heap.
++ Go code will only be permitted to use pointers to those types.
++ Allocating an instance of such a struct and passing a pointer, or a
++ full struct value, to C code was always unsafe and unlikely to work
++ correctly; it is now forbidden.
++ The fix is to either rewrite the Go code to use only pointers, or to
++ ensure that the Go code sees the full definition of the struct by
++ including the appropriate C header file.
++
++
+ X.509 CommonName deprecation
+
+
+--
+2.27.0
+
diff --git a/0002-release-branch.go1.15-cmd-go-fix-mod_get_fallback-te.patch b/0002-release-branch.go1.15-cmd-go-fix-mod_get_fallback-te.patch
new file mode 100644
index 0000000..6b855ba
--- /dev/null
+++ b/0002-release-branch.go1.15-cmd-go-fix-mod_get_fallback-te.patch
@@ -0,0 +1,38 @@
+From aaef93bba34740d793e987d95355feb312f01cfd Mon Sep 17 00:00:00 2001
+From: Jay Conrod
+Date: Wed, 20 Jan 2021 09:45:03 -0500
+Subject: [PATCH 02/44] [release-branch.go1.15] cmd/go: fix mod_get_fallback
+ test
+
+Fixes #43797
+
+Change-Id: I3d791d0ac9ce0b523c78c649aaf5e339a7f63b76
+Reviewed-on: https://go-review.googlesource.com/c/go/+/284797
+Trust: Jay Conrod
+Run-TryBot: Jay Conrod
+Reviewed-by: Bryan C. Mills
+TryBot-Result: Go Bot
+(cherry picked from commit be28e5abc5ddca0d6b2d8c91b7bb9c05717154e7)
+Reviewed-on: https://go-review.googlesource.com/c/go/+/284799
+
+Conflict:NA
+Reference:https://github.com/golang/go/commit/aaef93bba34740d793e987d95355feb312f01cfd
+
+---
+ src/cmd/go/testdata/script/mod_get_fallback.txt | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/cmd/go/testdata/script/mod_get_fallback.txt b/src/cmd/go/testdata/script/mod_get_fallback.txt
+index a9834a324e..9733fa366b 100644
+--- a/src/cmd/go/testdata/script/mod_get_fallback.txt
++++ b/src/cmd/go/testdata/script/mod_get_fallback.txt
+@@ -6,5 +6,5 @@ env GOPROXY=https://proxy.golang.org,direct
+ env GOSUMDB=off
+
+ go get -x -v -d golang.org/x/tools/cmd/goimports
+-stderr '# get https://proxy.golang.org/golang.org/x/tools/@latest'
++stderr '# get https://proxy.golang.org/golang.org/x/tools/@v/list'
+ ! stderr '# get https://golang.org'
+--
+2.27.0
+
diff --git a/0003-release-branch.go1.15-internal-execabs-only-run-test.patch b/0003-release-branch.go1.15-internal-execabs-only-run-test.patch
new file mode 100644
index 0000000..bfa22ef
--- /dev/null
+++ b/0003-release-branch.go1.15-internal-execabs-only-run-test.patch
@@ -0,0 +1,54 @@
+From e540758b604dd46b682593e284cf77a61ce3fde6 Mon Sep 17 00:00:00 2001
+From: Roland Shoemaker
+Date: Wed, 20 Jan 2021 09:06:12 -0800
+Subject: [PATCH 03/44] [release-branch.go1.15] internal/execabs: only run
+ tests on platforms that support them
+
+Fixes #43793
+
+Change-Id: I3bf022a28b194f0089ea96d93e56bbd9fb7e0aa8
+Reviewed-on: https://go-review.googlesource.com/c/go/+/285056
+Trust: Roland Shoemaker
+Run-TryBot: Roland Shoemaker
+Reviewed-by: Dmitri Shuralyov
+
+Conflict:NA
+Reference:https://github.com/golang/go/commit/e540758b604dd46b682593e284cf77a61ce3fde6
+
+---
+ src/internal/execabs/execabs_test.go | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/src/internal/execabs/execabs_test.go b/src/internal/execabs/execabs_test.go
+index a0b88dd2a0..1a197b8701 100644
+--- a/src/internal/execabs/execabs_test.go
++++ b/src/internal/execabs/execabs_test.go
+@@ -7,6 +7,7 @@ package execabs
+ import (
+ "context"
+ "fmt"
++ "internal/testenv"
+ "io/ioutil"
+ "os"
+ "os/exec"
+@@ -30,6 +31,8 @@ func TestFixCmd(t *testing.T) {
+ }
+
+ func TestCommand(t *testing.T) {
++ testenv.MustHaveExec(t)
++
+ for _, cmd := range []func(string) *Cmd{
+ func(s string) *Cmd { return Command(s) },
+ func(s string) *Cmd { return CommandContext(context.Background(), s) },
+@@ -71,6 +74,8 @@ func TestCommand(t *testing.T) {
+ }
+
+ func TestLookPath(t *testing.T) {
++ testenv.MustHaveExec(t)
++
+ tmpDir, err := ioutil.TempDir("", "execabs-test")
+ if err != nil {
+ t.Fatalf("ioutil.TempDir failed: %s", err)
+--
+2.27.0
+
diff --git a/0004-release-branch.go1.15-cmd-compile-don-t-short-circui.patch b/0004-release-branch.go1.15-cmd-compile-don-t-short-circui.patch
new file mode 100644
index 0000000..c2211d5
--- /dev/null
+++ b/0004-release-branch.go1.15-cmd-compile-don-t-short-circui.patch
@@ -0,0 +1,154 @@
+From 27d5fccd2119099c70ab6a4418626beac7a97b4b Mon Sep 17 00:00:00 2001
+From: Keith Randall
+Date: Thu, 7 Jan 2021 14:57:53 -0800
+Subject: [PATCH 04/44] [release-branch.go1.15] cmd/compile: don't
+ short-circuit copies whose source is volatile
+
+Current optimization: When we copy a->b and then b->c, we might as well
+copy a->c instead of b->c (then b might be dead and go away).
+
+*Except* if a is a volatile location (might be clobbered by a call).
+In that case, we really do want to copy a immediately, because there
+might be a call before we can do the a->c copy.
+
+User calls can't happen in between, because the rule matches up the
+memory states. But calls inserted for memory barriers, particularly
+runtime.typedmemmove, can.
+
+(I guess we could introduce a register-calling-convention version
+of runtime.typedmemmove, but that seems a bigger change than this one.)
+
+Fixes #43575
+
+Change-Id: Ifa518bb1a6f3a8dd46c352d4fd54ea9713b3eb1a
+Reviewed-on: https://go-review.googlesource.com/c/go/+/282492
+Trust: Keith Randall
+Trust: Josh Bleecher Snyder
+Run-TryBot: Keith Randall
+TryBot-Result: Go Bot
+Reviewed-by: Josh Bleecher Snyder
+(cherry picked from commit 304f769ffc68e64244266b3aadbf91e6738c0064)
+Reviewed-on: https://go-review.googlesource.com/c/go/+/282558
+Trust: Dmitri Shuralyov
+
+Conflict:NA
+Reference:https://github.com/golang/go/commit/27d5fccd2119099c70ab6a4418626beac7a97b4b
+
+---
+ .../compile/internal/ssa/gen/generic.rules | 4 +-
+ .../compile/internal/ssa/rewritegeneric.go | 8 ++--
+ test/fixedbugs/issue43570.go | 40 +++++++++++++++++++
+ 3 files changed, 46 insertions(+), 6 deletions(-)
+ create mode 100644 test/fixedbugs/issue43570.go
+
+diff --git a/src/cmd/compile/internal/ssa/gen/generic.rules b/src/cmd/compile/internal/ssa/gen/generic.rules
+index ed5bfc81fd..8bbe913380 100644
+--- a/src/cmd/compile/internal/ssa/gen/generic.rules
++++ b/src/cmd/compile/internal/ssa/gen/generic.rules
+@@ -2404,7 +2404,7 @@
+ (Move {t1} [s] dst tmp1 midmem:(Move {t2} [s] tmp2 src _))
+ && t1.Compare(t2) == types.CMPeq
+ && isSamePtr(tmp1, tmp2)
+- && isStackPtr(src)
++ && isStackPtr(src) && !isVolatile(src)
+ && disjoint(src, s, tmp2, s)
+ && (disjoint(src, s, dst, s) || isInlinableMemmove(dst, src, s, config))
+ => (Move {t1} [s] dst src midmem)
+@@ -2413,7 +2413,7 @@
+ (Move {t1} [s] dst tmp1 midmem:(VarDef (Move {t2} [s] tmp2 src _)))
+ && t1.Compare(t2) == types.CMPeq
+ && isSamePtr(tmp1, tmp2)
+- && isStackPtr(src)
++ && isStackPtr(src) && !isVolatile(src)
+ && disjoint(src, s, tmp2, s)
+ && (disjoint(src, s, dst, s) || isInlinableMemmove(dst, src, s, config))
+ => (Move {t1} [s] dst src midmem)
+diff --git a/src/cmd/compile/internal/ssa/rewritegeneric.go b/src/cmd/compile/internal/ssa/rewritegeneric.go
+index 9f4e1b95bd..6a09616aad 100644
+--- a/src/cmd/compile/internal/ssa/rewritegeneric.go
++++ b/src/cmd/compile/internal/ssa/rewritegeneric.go
+@@ -13666,7 +13666,7 @@ func rewriteValuegeneric_OpMove(v *Value) bool {
+ return true
+ }
+ // match: (Move {t1} [s] dst tmp1 midmem:(Move {t2} [s] tmp2 src _))
+- // cond: t1.Compare(t2) == types.CMPeq && isSamePtr(tmp1, tmp2) && isStackPtr(src) && disjoint(src, s, tmp2, s) && (disjoint(src, s, dst, s) || isInlinableMemmove(dst, src, s, config))
++ // cond: t1.Compare(t2) == types.CMPeq && isSamePtr(tmp1, tmp2) && isStackPtr(src) && !isVolatile(src) && disjoint(src, s, tmp2, s) && (disjoint(src, s, dst, s) || isInlinableMemmove(dst, src, s, config))
+ // result: (Move {t1} [s] dst src midmem)
+ for {
+ s := auxIntToInt64(v.AuxInt)
+@@ -13680,7 +13680,7 @@ func rewriteValuegeneric_OpMove(v *Value) bool {
+ t2 := auxToType(midmem.Aux)
+ src := midmem.Args[1]
+ tmp2 := midmem.Args[0]
+- if !(t1.Compare(t2) == types.CMPeq && isSamePtr(tmp1, tmp2) && isStackPtr(src) && disjoint(src, s, tmp2, s) && (disjoint(src, s, dst, s) || isInlinableMemmove(dst, src, s, config))) {
++ if !(t1.Compare(t2) == types.CMPeq && isSamePtr(tmp1, tmp2) && isStackPtr(src) && !isVolatile(src) && disjoint(src, s, tmp2, s) && (disjoint(src, s, dst, s) || isInlinableMemmove(dst, src, s, config))) {
+ break
+ }
+ v.reset(OpMove)
+@@ -13690,7 +13690,7 @@ func rewriteValuegeneric_OpMove(v *Value) bool {
+ return true
+ }
+ // match: (Move {t1} [s] dst tmp1 midmem:(VarDef (Move {t2} [s] tmp2 src _)))
+- // cond: t1.Compare(t2) == types.CMPeq && isSamePtr(tmp1, tmp2) && isStackPtr(src) && disjoint(src, s, tmp2, s) && (disjoint(src, s, dst, s) || isInlinableMemmove(dst, src, s, config))
++ // cond: t1.Compare(t2) == types.CMPeq && isSamePtr(tmp1, tmp2) && isStackPtr(src) && !isVolatile(src) && disjoint(src, s, tmp2, s) && (disjoint(src, s, dst, s) || isInlinableMemmove(dst, src, s, config))
+ // result: (Move {t1} [s] dst src midmem)
+ for {
+ s := auxIntToInt64(v.AuxInt)
+@@ -13708,7 +13708,7 @@ func rewriteValuegeneric_OpMove(v *Value) bool {
+ t2 := auxToType(midmem_0.Aux)
+ src := midmem_0.Args[1]
+ tmp2 := midmem_0.Args[0]
+- if !(t1.Compare(t2) == types.CMPeq && isSamePtr(tmp1, tmp2) && isStackPtr(src) && disjoint(src, s, tmp2, s) && (disjoint(src, s, dst, s) || isInlinableMemmove(dst, src, s, config))) {
++ if !(t1.Compare(t2) == types.CMPeq && isSamePtr(tmp1, tmp2) && isStackPtr(src) && !isVolatile(src) && disjoint(src, s, tmp2, s) && (disjoint(src, s, dst, s) || isInlinableMemmove(dst, src, s, config))) {
+ break
+ }
+ v.reset(OpMove)
+diff --git a/test/fixedbugs/issue43570.go b/test/fixedbugs/issue43570.go
+new file mode 100644
+index 0000000000..d073fde5f6
+--- /dev/null
++++ b/test/fixedbugs/issue43570.go
+@@ -0,0 +1,40 @@
++// run
++
++// 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 "fmt"
++
++type T [8]*int
++
++//go:noinline
++func f(x int) T {
++ return T{}
++}
++
++//go:noinline
++func g(x int, t T) {
++ if t != (T{}) {
++ panic(fmt.Sprintf("bad: %v", t))
++ }
++}
++
++func main() {
++ const N = 10000
++ var q T
++ func() {
++ for i := 0; i < N; i++ {
++ q = f(0)
++ g(0, q)
++ sink = make([]byte, 1024)
++ }
++ }()
++ // Note that the closure is a trick to get the write to q to be a
++ // write to a pointer that is known to be non-nil and requires
++ // a write barrier.
++}
++
++var sink []byte
+--
+2.27.0
+
diff --git a/0005-release-branch.go1.15-cmd-go-fix-get_update_unknown_.patch b/0005-release-branch.go1.15-cmd-go-fix-get_update_unknown_.patch
new file mode 100644
index 0000000..7c01a19
--- /dev/null
+++ b/0005-release-branch.go1.15-cmd-go-fix-get_update_unknown_.patch
@@ -0,0 +1,47 @@
+From 9bb97ea047890e900dae04202a231685492c4b18 Mon Sep 17 00:00:00 2001
+From: Jay Conrod
+Date: Fri, 22 Jan 2021 16:59:16 -0500
+Subject: [PATCH 05/44] [release-branch.go1.15] cmd/go: fix
+ get_update_unknown_protocol test
+
+This test needs to run in GOPATH mode. It broke when a go.mod file was
+added to github.com/golang/example. This change sets GO111MODULE=off,
+which matches master since CL 255051.
+
+Fixes #43861
+
+Change-Id: I9ea109a99509fac3185756a0f0d852a84c677bf5
+Reviewed-on: https://go-review.googlesource.com/c/go/+/285956
+Trust: Jay Conrod
+Run-TryBot: Jay Conrod
+TryBot-Result: Go Bot
+Reviewed-by: Bryan C. Mills
+
+Conflict:NA
+Reference:https://github.com/golang/go/commit/9bb97ea047890e900dae04202a231685492c4b18
+
+---
+ src/cmd/go/testdata/script/get_update_unknown_protocol.txt | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/src/cmd/go/testdata/script/get_update_unknown_protocol.txt b/src/cmd/go/testdata/script/get_update_unknown_protocol.txt
+index 85c2e24bc8..b00adea70b 100644
+--- a/src/cmd/go/testdata/script/get_update_unknown_protocol.txt
++++ b/src/cmd/go/testdata/script/get_update_unknown_protocol.txt
+@@ -1,5 +1,6 @@
+ [!net] skip
+ [!exec:git] skip
++env GO111MODULE=off
+
+ # Clone the repo via HTTPS manually.
+ exec git clone -q https://github.com/golang/example github.com/golang/example
+@@ -10,4 +11,4 @@ cd github.com/golang/example
+ exec git remote set-url origin xyz://github.com/golang/example
+ exec git config --local url.https://github.com/.insteadOf xyz://github.com/
+
+-go get -d -u -f github.com/golang/example/hello
+\ No newline at end of file
++go get -d -u -f github.com/golang/example/hello
+--
+2.27.0
+
diff --git a/0006-release-branch.go1.15-net-http-update-bundled-x-net-.patch b/0006-release-branch.go1.15-net-http-update-bundled-x-net-.patch
new file mode 100644
index 0000000..35e6235
--- /dev/null
+++ b/0006-release-branch.go1.15-net-http-update-bundled-x-net-.patch
@@ -0,0 +1,106 @@
+From a01db0df00fed281f6a9673eb93fe6acae6197cf Mon Sep 17 00:00:00 2001
+From: Damien Neil
+Date: Fri, 29 Jan 2021 11:01:37 -0800
+Subject: [PATCH 06/44] [release-branch.go1.15] net/http: update bundled
+ x/net/http2
+
+Updates bundled http2 to x/net git rev 16c2bbf55 for:
+
+ http2: send a nil error if we cancel a delayed body write
+ https://golang.org/cl/288013
+
+ http2: wait until the request body has been written
+ https://golang.org/cl/288012
+
+Created by:
+
+go mod edit -replace=golang.org/x/net=golang.org/x/net@release-branch.go1.15-bundle
+GOFLAGS='-mod=mod' go generate -run=bundle std
+go mod edit -dropreplace=golang.org/x/net
+go get -d golang.org/x/net@release-branch.go1.15
+go mod tidy
+go mod vendor
+
+Fixes golang/go#42539
+
+Change-Id: I299c6d4a67ebc036e45c978e4d03cba73717b363
+Reviewed-on: https://go-review.googlesource.com/c/go/+/288112
+Trust: Damien Neil
+Run-TryBot: Damien Neil
+Reviewed-by: Dmitri Shuralyov
+
+Conflict:NA
+Reference:https://github.com/golang/go/commit/a01db0df00fed281f6a9673eb93fe6acae6197cf
+
+---
+ src/net/http/h2_bundle.go | 12 ++++++++++--
+ 1 file changed, 10 insertions(+), 2 deletions(-)
+
+diff --git a/src/net/http/h2_bundle.go b/src/net/http/h2_bundle.go
+index b03b84d2f3..678c6eb9d4 100644
+--- a/src/net/http/h2_bundle.go
++++ b/src/net/http/h2_bundle.go
+@@ -7592,6 +7592,9 @@ func (cc *http2ClientConn) roundTrip(req *Request) (res *Response, gotErrAfterRe
+ // we can keep it.
+ bodyWriter.cancel()
+ cs.abortRequestBodyWrite(http2errStopReqBodyWrite)
++ if hasBody && !bodyWritten {
++ <-bodyWriter.resc
++ }
+ }
+ if re.err != nil {
+ cc.forgetStreamID(cs.ID)
+@@ -7612,6 +7615,7 @@ func (cc *http2ClientConn) roundTrip(req *Request) (res *Response, gotErrAfterRe
+ } else {
+ bodyWriter.cancel()
+ cs.abortRequestBodyWrite(http2errStopReqBodyWriteAndCancel)
++ <-bodyWriter.resc
+ }
+ cc.forgetStreamID(cs.ID)
+ return nil, cs.getStartedWrite(), http2errTimeout
+@@ -7621,6 +7625,7 @@ func (cc *http2ClientConn) roundTrip(req *Request) (res *Response, gotErrAfterRe
+ } else {
+ bodyWriter.cancel()
+ cs.abortRequestBodyWrite(http2errStopReqBodyWriteAndCancel)
++ <-bodyWriter.resc
+ }
+ cc.forgetStreamID(cs.ID)
+ return nil, cs.getStartedWrite(), ctx.Err()
+@@ -7630,6 +7635,7 @@ func (cc *http2ClientConn) roundTrip(req *Request) (res *Response, gotErrAfterRe
+ } else {
+ bodyWriter.cancel()
+ cs.abortRequestBodyWrite(http2errStopReqBodyWriteAndCancel)
++ <-bodyWriter.resc
+ }
+ cc.forgetStreamID(cs.ID)
+ return nil, cs.getStartedWrite(), http2errRequestCanceled
+@@ -7639,6 +7645,7 @@ func (cc *http2ClientConn) roundTrip(req *Request) (res *Response, gotErrAfterRe
+ // forgetStreamID.
+ return nil, cs.getStartedWrite(), cs.resetErr
+ case err := <-bodyWriter.resc:
++ bodyWritten = true
+ // Prefer the read loop's response, if available. Issue 16102.
+ select {
+ case re := <-readLoopResCh:
+@@ -7649,7 +7656,6 @@ func (cc *http2ClientConn) roundTrip(req *Request) (res *Response, gotErrAfterRe
+ cc.forgetStreamID(cs.ID)
+ return nil, cs.getStartedWrite(), err
+ }
+- bodyWritten = true
+ if d := cc.responseHeaderTimeout(); d != 0 {
+ timer := time.NewTimer(d)
+ defer timer.Stop()
+@@ -9060,7 +9066,9 @@ func (t *http2Transport) getBodyWriterState(cs *http2clientStream, body io.Reade
+
+ func (s http2bodyWriterState) cancel() {
+ if s.timer != nil {
+- s.timer.Stop()
++ if s.timer.Stop() {
++ s.resc <- nil
++ }
+ }
+ }
+
+--
+2.27.0
+
diff --git a/0007-release-branch.go1.15-cmd-go-don-t-lookup-the-path-f.patch b/0007-release-branch.go1.15-cmd-go-don-t-lookup-the-path-f.patch
new file mode 100644
index 0000000..69747bb
--- /dev/null
+++ b/0007-release-branch.go1.15-cmd-go-don-t-lookup-the-path-f.patch
@@ -0,0 +1,208 @@
+From 4a48a7d7bda25a844a7e597e96041b55c9f32d4d Mon Sep 17 00:00:00 2001
+From: Jay Conrod
+Date: Fri, 22 Jan 2021 14:27:24 -0500
+Subject: [PATCH 07/44] [release-branch.go1.15] cmd/go: don't lookup the path
+ for CC when invoking cgo
+
+Previously, if CC was a path without separators (like gcc or clang),
+we'd look it up in PATH in cmd/go using internal/execabs.LookPath,
+then pass the resolved path to cgo in CC.
+
+This caused a regression: if the directory in PATH containing CC has a
+space, cgo splits it and interprets it as multiple arguments.
+
+With this change, cmd/go no longer resolves CC before invoking
+cgo. cgo does the path lookup on each invocation. This reverts the
+security fix CL 284780, but that was redundant with the addition of
+internal/execabs (CL 955304), which still protects us.
+
+NOTE: This CL includes a related test fix from CL 286292.
+
+Fixes #43860
+
+Change-Id: I65d91a1e303856df8653881eb6e2e75a3bf95c49
+Reviewed-on: https://go-review.googlesource.com/c/go/+/285873
+Trust: Jay Conrod
+Run-TryBot: Jay Conrod
+TryBot-Result: Go Bot
+Reviewed-by: Bryan C. Mills
+(cherry picked from commit a2cef9b544708ecae983ed8836ee2425a28aab68)
+Reviewed-on: https://go-review.googlesource.com/c/go/+/285954
+Run-TryBot: Dmitri Shuralyov
+
+Conflict:NA
+Reference:https://github.com/golang/go/commit/4a48a7d7bda25a844a7e597e96041b55c9f32d4d
+
+---
+ src/cmd/go/internal/work/action.go | 3 -
+ src/cmd/go/internal/work/exec.go | 27 ++-------
+ src/cmd/go/testdata/script/cgo_path.txt | 12 +++-
+ src/cmd/go/testdata/script/cgo_path_space.txt | 56 +++++++++++++++++++
+ 4 files changed, 72 insertions(+), 26 deletions(-)
+ create mode 100644 src/cmd/go/testdata/script/cgo_path_space.txt
+
+diff --git a/src/cmd/go/internal/work/action.go b/src/cmd/go/internal/work/action.go
+index 03ca301bdd..6b5f9e4807 100644
+--- a/src/cmd/go/internal/work/action.go
++++ b/src/cmd/go/internal/work/action.go
+@@ -56,9 +56,6 @@ type Builder struct {
+ id sync.Mutex
+ toolIDCache map[string]string // tool name -> tool ID
+ buildIDCache map[string]string // file name -> build ID
+-
+- cgoEnvOnce sync.Once
+- cgoEnvCache []string
+ }
+
+ // NOTE: Much of Action would not need to be exported if not for test.
+diff --git a/src/cmd/go/internal/work/exec.go b/src/cmd/go/internal/work/exec.go
+index f5f9951afa..eb1efd9f82 100644
+--- a/src/cmd/go/internal/work/exec.go
++++ b/src/cmd/go/internal/work/exec.go
+@@ -1081,7 +1081,10 @@ func (b *Builder) vet(a *Action) error {
+ }
+
+ // TODO(rsc): Why do we pass $GCCGO to go vet?
+- env := b.cgoEnv()
++ env := b.cCompilerEnv()
++ if cfg.BuildToolchainName == "gccgo" {
++ env = append(env, "GCCGO="+BuildToolchain.compiler())
++ }
+
+ p := a.Package
+ tool := VetTool
+@@ -2015,24 +2018,6 @@ func (b *Builder) cCompilerEnv() []string {
+ return []string{"TERM=dumb"}
+ }
+
+-// cgoEnv returns environment variables to set when running cgo.
+-// Some of these pass through to cgo running the C compiler,
+-// so it includes cCompilerEnv.
+-func (b *Builder) cgoEnv() []string {
+- b.cgoEnvOnce.Do(func() {
+- cc, err := exec.LookPath(b.ccExe()[0])
+- if err != nil || filepath.Base(cc) == cc { // reject relative path
+- cc = "/missing-cc"
+- }
+- gccgo := GccgoBin
+- if filepath.Base(gccgo) == gccgo { // reject relative path
+- gccgo = "/missing-gccgo"
+- }
+- b.cgoEnvCache = append(b.cCompilerEnv(), "CC="+cc, "GCCGO="+gccgo)
+- })
+- return b.cgoEnvCache
+-}
+-
+ // mkdir makes the named directory.
+ func (b *Builder) Mkdir(dir string) error {
+ // Make Mkdir(a.Objdir) a no-op instead of an error when a.Objdir == "".
+@@ -2622,7 +2607,7 @@ func (b *Builder) cgo(a *Action, cgoExe, objdir string, pcCFLAGS, pcLDFLAGS, cgo
+ // along to the host linker. At this point in the code, cgoLDFLAGS
+ // consists of the original $CGO_LDFLAGS (unchecked) and all the
+ // flags put together from source code (checked).
+- cgoenv := b.cgoEnv()
++ cgoenv := b.cCompilerEnv()
+ if len(cgoLDFLAGS) > 0 {
+ flags := make([]string, len(cgoLDFLAGS))
+ for i, f := range cgoLDFLAGS {
+@@ -2843,7 +2828,7 @@ func (b *Builder) dynimport(a *Action, p *load.Package, objdir, importGo, cgoExe
+ if p.Standard && p.ImportPath == "runtime/cgo" {
+ cgoflags = []string{"-dynlinker"} // record path to dynamic linker
+ }
+- return b.run(a, p.Dir, p.ImportPath, b.cgoEnv(), cfg.BuildToolexec, cgoExe, "-dynpackage", p.Name, "-dynimport", dynobj, "-dynout", importGo, cgoflags)
++ return b.run(a, p.Dir, p.ImportPath, b.cCompilerEnv(), cfg.BuildToolexec, cgoExe, "-dynpackage", p.Name, "-dynimport", dynobj, "-dynout", importGo, cgoflags)
+ }
+
+ // Run SWIG on all SWIG input files.
+diff --git a/src/cmd/go/testdata/script/cgo_path.txt b/src/cmd/go/testdata/script/cgo_path.txt
+index 0d15998426..3eba71bc15 100644
+--- a/src/cmd/go/testdata/script/cgo_path.txt
++++ b/src/cmd/go/testdata/script/cgo_path.txt
+@@ -1,12 +1,20 @@
+ [!cgo] skip
+
++# Set CC explicitly to something that requires a PATH lookup.
++# Normally, the default is gcc or clang, but if CC was set during make.bash,
++# that becomes the default.
++[exec:clang] env CC=clang
++[exec:gcc] env CC=gcc
++[!exec:clang] [!exec:gcc] skip 'Unknown C compiler'
++
+ env GOCACHE=$WORK/gocache # Looking for compile flags, so need a clean cache.
+ [!windows] env PATH=.:$PATH
+-[!windows] chmod 0777 p/gcc p/clang
++[!windows] chmod 0755 p/gcc p/clang
+ [!windows] exists -exec p/gcc p/clang
+ [windows] exists -exec p/gcc.bat p/clang.bat
+ ! exists p/bug.txt
+-go build -x
++! go build -x
++stderr '^cgo: exec (clang|gcc): (clang|gcc) resolves to executable in current directory \(.[/\\](clang|gcc)(.bat)?\)$'
+ ! exists p/bug.txt
+
+ -- go.mod --
+diff --git a/src/cmd/go/testdata/script/cgo_path_space.txt b/src/cmd/go/testdata/script/cgo_path_space.txt
+new file mode 100644
+index 0000000000..654295dc69
+--- /dev/null
++++ b/src/cmd/go/testdata/script/cgo_path_space.txt
+@@ -0,0 +1,56 @@
++# Check that if the PATH directory containing the C compiler has a space,
++# we can still use that compiler with cgo.
++# Verifies #43808.
++[!cgo] skip
++
++# Set CC explicitly to something that requires a PATH lookup.
++# Normally, the default is gcc or clang, but if CC was set during make.bash,
++# that becomes the default.
++[exec:clang] env CC=clang
++[exec:gcc] env CC=gcc
++[!exec:clang] [!exec:gcc] skip 'Unknown C compiler'
++
++[!windows] chmod 0755 $WORK/'program files'/clang
++[!windows] chmod 0755 $WORK/'program files'/gcc
++[!windows] exists -exec $WORK/'program files'/clang
++[!windows] exists -exec $WORK/'program files'/gcc
++[!windows] env PATH=$WORK/'program files':$PATH
++[windows] exists -exec $WORK/'program files'/gcc.bat
++[windows] exists -exec $WORK/'program files'/clang.bat
++[windows] env PATH=$WORK\'program files';%PATH%
++
++! exists $WORK/log.txt
++? go build -x
++exists $WORK/log.txt
++rm $WORK/log.txt
++
++# TODO(#41400, #43078): when CC is set explicitly, it should be allowed to
++# contain spaces separating arguments, and it should be possible to quote
++# arguments with spaces (including the path), as in CGO_CFLAGS and other
++# variables. For now, this doesn't work.
++[!windows] env CC=$WORK/'program files'/gcc
++[windows] env CC=$WORK\'program files'\gcc.bat
++! go build -x
++! exists $WORK/log.txt
++
++-- go.mod --
++module m
++
++-- m.go --
++package m
++
++// #define X 1
++import "C"
++
++-- $WORK/program files/gcc --
++#!/bin/sh
++
++echo ok >$WORK/log.txt
++-- $WORK/program files/clang --
++#!/bin/sh
++
++echo ok >$WORK/log.txt
++-- $WORK/program files/gcc.bat --
++echo ok >%WORK%\log.txt
++-- $WORK/program files/clang.bat --
++echo ok >%WORK%\log.txt
+--
+2.27.0
+
diff --git a/0008-release-branch.go1.15-cmd-link-internal-ld-pe-fix-se.patch b/0008-release-branch.go1.15-cmd-link-internal-ld-pe-fix-se.patch
new file mode 100644
index 0000000..b19737a
--- /dev/null
+++ b/0008-release-branch.go1.15-cmd-link-internal-ld-pe-fix-se.patch
@@ -0,0 +1,58 @@
+From aa9b48cd1837644a1555fd7a370800924cef627a Mon Sep 17 00:00:00 2001
+From: Derek Parker
+Date: Wed, 25 Nov 2020 16:31:57 +0000
+Subject: [PATCH 08/44] [release-branch.go1.15] cmd/link/internal/ld/pe: fix
+ segfault adding resource section
+
+The resource symbol may have been copied to the mmap'd
+output buffer. If so, certain conditions can cause that
+mmap'd output buffer to be munmap'd before we get a chance
+to use it. To avoid any issues we copy the data to the heap
+when the resource symbol exists.
+
+Fixes #42384
+
+Change-Id: I32ef5420802d7313a3d965b8badfbcfb9f0fba4a
+GitHub-Last-Rev: 7b0f43011d06083ee3e871e48a87847636f738f9
+GitHub-Pull-Request: golang/go#42427
+Reviewed-on: https://go-review.googlesource.com/c/go/+/268018
+Run-TryBot: Carlos Amedee
+TryBot-Result: Go Bot
+Reviewed-by: Russ Cox
+Reviewed-by: Cherry Zhang
+Reviewed-by: Than McIntosh
+Trust: Carlos Amedee
+
+Conflict:NA
+Reference:https://github.com/golang/go/commit/aa9b48cd1837644a1555fd7a370800924cef627a
+
+---
+ src/cmd/link/internal/ld/pe.go | 12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+diff --git a/src/cmd/link/internal/ld/pe.go b/src/cmd/link/internal/ld/pe.go
+index c9cb25dbe5..5d68ca7d9c 100644
+--- a/src/cmd/link/internal/ld/pe.go
++++ b/src/cmd/link/internal/ld/pe.go
+@@ -1515,6 +1515,18 @@ func Asmbpe(ctxt *Link) {
+ case sys.AMD64, sys.I386, sys.ARM:
+ }
+
++ if rsrcsym != 0 {
++ // The resource symbol may have been copied to the mmap'd
++ // output buffer. If so, certain conditions can cause that
++ // mmap'd output buffer to be munmap'd before we get a chance
++ // to use it. To avoid any issues we copy the data to the heap
++ // when the resource symbol exists.
++ rsrc := ctxt.loader.Syms[rsrcsym]
++ data := make([]byte, len(rsrc.P))
++ copy(data, rsrc.P)
++ rsrc.P = data
++ }
++
+ t := pefile.addSection(".text", int(Segtext.Length), int(Segtext.Length))
+ t.characteristics = IMAGE_SCN_CNT_CODE | IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_READ
+ if ctxt.LinkMode == LinkExternal {
+--
+2.27.0
+
diff --git a/0009-release-branch.go1.15-cmd-internal-goobj2-fix-buglet.patch b/0009-release-branch.go1.15-cmd-internal-goobj2-fix-buglet.patch
new file mode 100644
index 0000000..97fea5b
--- /dev/null
+++ b/0009-release-branch.go1.15-cmd-internal-goobj2-fix-buglet.patch
@@ -0,0 +1,73 @@
+From 58dc4452620ebefa75742661c538b8406b213b4a Mon Sep 17 00:00:00 2001
+From: Than McIntosh
+Date: Tue, 15 Dec 2020 15:54:25 -0500
+Subject: [PATCH 09/44] [release-branch.go1.15] cmd/internal/goobj2: fix buglet
+ in object file reader
+
+The code in the Go object file reader was casting a pointer to mmaped
+memory into a large array prior to performing a read of the
+relocations section:
+
+ return (*[1<<20]Reloc)(unsafe.Pointer(&r.b[off]))[:n:n]
+
+For very large object files, this artificial array isn't large enough
+(that is, there are more than 1048576 relocs to read), so update the
+code to use a larger artifical array size.
+
+Fixes #43214.
+Updates #41621.
+
+Change-Id: Ic047c8aef4f8a3839f2e7e3594bce652ebd6bd5b
+Reviewed-on: https://go-review.googlesource.com/c/go/+/278492
+Run-TryBot: Than McIntosh
+TryBot-Result: Go Bot
+Reviewed-by: Cherry Zhang
+Reviewed-by: Jeremy Faller
+Trust: Than McIntosh
+(cherry picked from commit f4e7a6b905ce60448e506a3f6578d01b60602cdd)
+Reviewed-on: https://go-review.googlesource.com/c/go/+/278673
+
+Conflict:NA
+Reference:https://github.com/golang/go/commit/58dc4452620ebefa75742661c538b8406b213b4a
+
+---
+ src/cmd/internal/goobj2/objfile.go | 9 +++++++--
+ 1 file changed, 7 insertions(+), 2 deletions(-)
+
+diff --git a/src/cmd/internal/goobj2/objfile.go b/src/cmd/internal/goobj2/objfile.go
+index 7f728e4f76..aba9b9856e 100644
+--- a/src/cmd/internal/goobj2/objfile.go
++++ b/src/cmd/internal/goobj2/objfile.go
+@@ -379,6 +379,11 @@ func (a *Aux) Write(w *Writer) { w.Bytes(a[:]) }
+ // for testing
+ func (a *Aux) fromBytes(b []byte) { copy(a[:], b) }
+
++// Used to construct an artifically large array type when reading an
++// item from the object file relocs section or aux sym section (needs
++// to work on 32-bit as well as 64-bit). See issue 41621.
++const huge = (1<<31 - 1) / RelocSize
++
+ // Referenced symbol name.
+ //
+ // Serialized format:
+@@ -652,7 +657,7 @@ func (r *Reader) Reloc(i int, j int) *Reloc {
+ func (r *Reader) Relocs(i int) []Reloc {
+ off := r.RelocOff(i, 0)
+ n := r.NReloc(i)
+- return (*[1 << 20]Reloc)(unsafe.Pointer(&r.b[off]))[:n:n]
++ return (*[huge]Reloc)(unsafe.Pointer(&r.b[off]))[:n:n]
+ }
+
+ // NAux returns the number of aux symbols of the i-th symbol.
+@@ -678,7 +683,7 @@ func (r *Reader) Aux(i int, j int) *Aux {
+ func (r *Reader) Auxs(i int) []Aux {
+ off := r.AuxOff(i, 0)
+ n := r.NAux(i)
+- return (*[1 << 20]Aux)(unsafe.Pointer(&r.b[off]))[:n:n]
++ return (*[huge]Aux)(unsafe.Pointer(&r.b[off]))[:n:n]
+ }
+
+ // DataOff returns the offset of the i-th symbol's data.
+--
+2.27.0
+
diff --git a/0010-release-branch.go1.15-runtime-don-t-adjust-timer-pp-.patch b/0010-release-branch.go1.15-runtime-don-t-adjust-timer-pp-.patch
new file mode 100644
index 0000000..8484da4
--- /dev/null
+++ b/0010-release-branch.go1.15-runtime-don-t-adjust-timer-pp-.patch
@@ -0,0 +1,72 @@
+From 3171f483775c7eb8d38b68f53d8fd5078db7f967 Mon Sep 17 00:00:00 2001
+From: Ian Lance Taylor
+Date: Tue, 19 Jan 2021 21:30:36 -0800
+Subject: [PATCH 10/44] [release-branch.go1.15] runtime: don't adjust timer pp
+ field in timerWaiting status
+
+Before this CL, the following sequence was possible:
+
+* GC scavenger starts and sets up scavenge.timer
+* GC calls readyForScavenger, but sysmon is sleeping
+* program calls runtime.GOMAXPROCS to shrink number of processors
+* procresize destroys a P, the one that scavenge.timer is on
+* (*pp).destroy calls moveTimers, which gets to the scavenger timer
+* scavenger timer is timerWaiting, and moveTimers clears t.pp
+* sysmon wakes up and calls wakeScavenger
+* wakeScavengers calls stopTimer on scavenger.timer, still timerWaiting
+* stopTimer calls deltimer which loads t.pp, which is still nil
+* stopTimer tries to increment deletedTimers on nil t.pp, and crashes
+
+The point of vulnerability is the time that t.pp is set to nil by
+moveTimers and the time that t.pp is set to non-nil by moveTimers,
+which is a few instructions at most. So it's not likely and in
+particular is quite unlikely on x86. But with a more relaxed memory
+model the area of vulnerability can be somewhat larger. This appears
+to tbe the cause of two builder failures in a few months on linux-mips.
+
+This CL fixes the problem by making moveTimers change the status from
+timerWaiting to timerMoving while t.pp is clear. That will cause
+deltimer to wait until the status is back to timerWaiting, at which
+point t.pp has been set again.
+
+For #43712
+Fixes #43833
+
+Change-Id: I66838319ecfbf15be66c1fac88d9bd40e2295852
+Reviewed-on: https://go-review.googlesource.com/c/go/+/284775
+Trust: Ian Lance Taylor
+Reviewed-by: Michael Knyszek
+Reviewed-by: Michael Pratt
+(cherry picked from commit d2d155d1ae8c704a37f42fd3ebb1f3846f78e4d4)
+Reviewed-on: https://go-review.googlesource.com/c/go/+/287092
+Run-TryBot: Carlos Amedee
+
+Conflict:NA
+Reference:https://github.com/golang/go/commit/3171f483775c7eb8d38b68f53d8fd5078db7f967
+
+---
+ src/runtime/time.go | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/src/runtime/time.go b/src/runtime/time.go
+index fdb5066b24..ec3eae9cca 100644
+--- a/src/runtime/time.go
++++ b/src/runtime/time.go
+@@ -594,8 +594,14 @@ func moveTimers(pp *p, timers []*timer) {
+ for {
+ switch s := atomic.Load(&t.status); s {
+ case timerWaiting:
++ if !atomic.Cas(&t.status, s, timerMoving) {
++ continue
++ }
+ t.pp = 0
+ doaddtimer(pp, t)
++ if !atomic.Cas(&t.status, timerMoving, timerWaiting) {
++ badTimer()
++ }
+ break loop
+ case timerModifiedEarlier, timerModifiedLater:
+ if !atomic.Cas(&t.status, s, timerMoving) {
+--
+2.27.0
+
diff --git a/0011-release-branch.go1.15-runtime-cgo-fix-Android-build-.patch b/0011-release-branch.go1.15-runtime-cgo-fix-Android-build-.patch
new file mode 100644
index 0000000..9fe1721
--- /dev/null
+++ b/0011-release-branch.go1.15-runtime-cgo-fix-Android-build-.patch
@@ -0,0 +1,82 @@
+From c3e1c3800bfb56bf1b0c3d696f59f42b16bd4fc2 Mon Sep 17 00:00:00 2001
+From: Elias Naur
+Date: Fri, 25 Dec 2020 11:14:11 +0100
+Subject: [PATCH 11/44] [release-branch.go1.15] runtime/cgo: fix Android build
+ with NDK 22
+
+Fixes #43406
+
+Change-Id: I7d2b70098a4ba4dcb325fb0be076043789b86135
+Reviewed-on: https://go-review.googlesource.com/c/go/+/280312
+Run-TryBot: Elias Naur
+TryBot-Result: Go Bot
+Reviewed-by: Ian Lance Taylor
+Trust: Elias Naur
+(cherry picked from commit 1d78139128d6d839d7da0aeb10b3e51b6c7c0749)
+Reviewed-on: https://go-review.googlesource.com/c/go/+/289149
+
+Conflict:NA
+Reference:https://github.com/golang/go/commit/c3e1c3800bfb56bf1b0c3d696f59f42b16bd4fc2
+
+---
+ src/runtime/cgo/gcc_linux_386.c | 2 +-
+ src/runtime/cgo/gcc_linux_amd64.c | 2 +-
+ src/runtime/cgo/gcc_linux_arm.c | 2 +-
+ src/runtime/cgo/gcc_linux_arm64.c | 2 +-
+ 4 files changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/src/runtime/cgo/gcc_linux_386.c b/src/runtime/cgo/gcc_linux_386.c
+index ece9f933c5..70c942aeb8 100644
+--- a/src/runtime/cgo/gcc_linux_386.c
++++ b/src/runtime/cgo/gcc_linux_386.c
+@@ -12,7 +12,7 @@ static void *threadentry(void*);
+ static void (*setg_gcc)(void*);
+
+ // This will be set in gcc_android.c for android-specific customization.
+-void (*x_cgo_inittls)(void **tlsg, void **tlsbase);
++void (*x_cgo_inittls)(void **tlsg, void **tlsbase) __attribute__((common));
+
+ void
+ x_cgo_init(G *g, void (*setg)(void*), void **tlsg, void **tlsbase)
+diff --git a/src/runtime/cgo/gcc_linux_amd64.c b/src/runtime/cgo/gcc_linux_amd64.c
+index 9134e0df92..f2bf6482cb 100644
+--- a/src/runtime/cgo/gcc_linux_amd64.c
++++ b/src/runtime/cgo/gcc_linux_amd64.c
+@@ -14,7 +14,7 @@ static void* threadentry(void*);
+ static void (*setg_gcc)(void*);
+
+ // This will be set in gcc_android.c for android-specific customization.
+-void (*x_cgo_inittls)(void **tlsg, void **tlsbase);
++void (*x_cgo_inittls)(void **tlsg, void **tlsbase) __attribute__((common));
+
+ void
+ x_cgo_init(G *g, void (*setg)(void*), void **tlsg, void **tlsbase)
+diff --git a/src/runtime/cgo/gcc_linux_arm.c b/src/runtime/cgo/gcc_linux_arm.c
+index 61855b96b2..5bc0fee90d 100644
+--- a/src/runtime/cgo/gcc_linux_arm.c
++++ b/src/runtime/cgo/gcc_linux_arm.c
+@@ -10,7 +10,7 @@
+
+ static void *threadentry(void*);
+
+-void (*x_cgo_inittls)(void **tlsg, void **tlsbase);
++void (*x_cgo_inittls)(void **tlsg, void **tlsbase) __attribute__((common));
+ static void (*setg_gcc)(void*);
+
+ void
+diff --git a/src/runtime/cgo/gcc_linux_arm64.c b/src/runtime/cgo/gcc_linux_arm64.c
+index 261c884ac9..17ff274fbb 100644
+--- a/src/runtime/cgo/gcc_linux_arm64.c
++++ b/src/runtime/cgo/gcc_linux_arm64.c
+@@ -12,7 +12,7 @@
+
+ static void *threadentry(void*);
+
+-void (*x_cgo_inittls)(void **tlsg, void **tlsbase);
++void (*x_cgo_inittls)(void **tlsg, void **tlsbase) __attribute__((common));
+ static void (*setg_gcc)(void*);
+
+ void
+--
+2.27.0
+
diff --git a/0013-release-branch.go1.15-internal-poll-if-copy_file_ran.patch b/0013-release-branch.go1.15-internal-poll-if-copy_file_ran.patch
new file mode 100644
index 0000000..6aee0f5
--- /dev/null
+++ b/0013-release-branch.go1.15-internal-poll-if-copy_file_ran.patch
@@ -0,0 +1,102 @@
+From 023c46676db26e75d244b1d38ccc4a4b8bfe3eef Mon Sep 17 00:00:00 2001
+From: Ian Lance Taylor
+Date: Sun, 14 Feb 2021 17:14:41 -0800
+Subject: [PATCH 13/44] [release-branch.go1.15] internal/poll: if
+ copy_file_range returns 0, assume it failed
+
+On current Linux kernels copy_file_range does not correctly handle
+files in certain special file systems, such as /proc. For those file
+systems it fails to copy any data and returns zero. This breaks Go's
+io.Copy for those files.
+
+Fix the problem by assuming that if copy_file_range returns 0 the
+first time it is called on a file, that that file is not supported.
+In that case fall back to just using read. This will force an extra
+system call when using io.Copy to copy a zero-sized normal file,
+but at least it will work correctly.
+
+For #36817
+For #44272
+Fixes #44273
+
+Change-Id: I02e81872cb70fda0ce5485e2ea712f219132e614
+Reviewed-on: https://go-review.googlesource.com/c/go/+/291989
+Trust: Ian Lance Taylor
+Run-TryBot: Ian Lance Taylor
+TryBot-Result: Go Bot
+Reviewed-by: Russ Cox
+(cherry picked from commit 30641e36aa5b547eee48565caa3078b0a2e7c185)
+Reviewed-on: https://go-review.googlesource.com/c/go/+/292289
+
+Conflict:NA
+Reference:https://github.com/golang/go/commit/023c46676db26e75d244b1d38ccc4a4b8bfe3eef
+
+---
+ src/internal/poll/copy_file_range_linux.go | 10 ++++++-
+ src/os/readfrom_linux_test.go | 32 ++++++++++++++++++++++
+ 2 files changed, 41 insertions(+), 1 deletion(-)
+
+diff --git a/src/internal/poll/copy_file_range_linux.go b/src/internal/poll/copy_file_range_linux.go
+index fc34aef4cb..01b242a4ea 100644
+--- a/src/internal/poll/copy_file_range_linux.go
++++ b/src/internal/poll/copy_file_range_linux.go
+@@ -112,7 +112,15 @@ func CopyFileRange(dst, src *FD, remain int64) (written int64, handled bool, err
+ return 0, false, nil
+ case nil:
+ if n == 0 {
+- // src is at EOF, which means we are done.
++ // If we did not read any bytes at all,
++ // then this file may be in a file system
++ // where copy_file_range silently fails.
++ // https://lore.kernel.org/linux-fsdevel/20210126233840.GG4626@dread.disaster.area/T/#m05753578c7f7882f6e9ffe01f981bc223edef2b0
++ if written == 0 {
++ return 0, false, nil
++ }
++ // Otherwise src is at EOF, which means
++ // we are done.
+ return written, true, nil
+ }
+ remain -= n
+diff --git a/src/os/readfrom_linux_test.go b/src/os/readfrom_linux_test.go
+index 00faf39fe5..aa3f050667 100644
+--- a/src/os/readfrom_linux_test.go
++++ b/src/os/readfrom_linux_test.go
+@@ -361,3 +361,35 @@ func (h *copyFileRangeHook) install() {
+ func (h *copyFileRangeHook) uninstall() {
+ *PollCopyFileRangeP = h.original
+ }
++
++// On some kernels copy_file_range fails on files in /proc.
++func TestProcCopy(t *testing.T) {
++ const cmdlineFile = "/proc/self/cmdline"
++ cmdline, err := ioutil.ReadFile(cmdlineFile)
++ if err != nil {
++ t.Skipf("can't read /proc file: %v", err)
++ }
++ in, err := Open(cmdlineFile)
++ if err != nil {
++ t.Fatal(err)
++ }
++ defer in.Close()
++ outFile := filepath.Join(t.TempDir(), "cmdline")
++ out, err := Create(outFile)
++ if err != nil {
++ t.Fatal(err)
++ }
++ if _, err := io.Copy(out, in); err != nil {
++ t.Fatal(err)
++ }
++ if err := out.Close(); err != nil {
++ t.Fatal(err)
++ }
++ copy, err := ioutil.ReadFile(outFile)
++ if err != nil {
++ t.Fatal(err)
++ }
++ if !bytes.Equal(cmdline, copy) {
++ t.Errorf("copy of %q got %q want %q\n", cmdlineFile, copy, cmdline)
++ }
++}
+--
+2.27.0
+
diff --git a/0014-release-branch.go1.15-internal-poll-netpollcheckerr-.patch b/0014-release-branch.go1.15-internal-poll-netpollcheckerr-.patch
new file mode 100644
index 0000000..4a9859a
--- /dev/null
+++ b/0014-release-branch.go1.15-internal-poll-netpollcheckerr-.patch
@@ -0,0 +1,166 @@
+From 30357d6ef6513b18fade686a629ab8d49987260f Mon Sep 17 00:00:00 2001
+From: Wei Fu
+Date: Sun, 24 Jan 2021 18:21:06 +0800
+Subject: [PATCH 14/44] [release-branch.go1.15] internal/poll: netpollcheckerr
+ before sendfile
+
+In net/http package, the ServeContent/ServeFile doesn't check the I/O
+timeout error from chunkWriter or *net.TCPConn, which means that both
+HTTP status and headers might be missing when WriteTimeout happens. If
+the poll.SendFile() doesn't check the *poll.FD state before sending
+data, the client will only receive the response body with status and
+report "malformed http response/status code".
+
+This patch is to enable netpollcheckerr before sendfile, which should
+align with normal *poll.FD.Write() and Splice().
+
+For #43822
+Fixes #44294
+
+Change-Id: I32517e3f261bab883a58b577b813ef189214b954
+Reviewed-on: https://go-review.googlesource.com/c/go/+/285914
+Reviewed-by: Emmanuel Odeke
+Trust: Emmanuel Odeke
+Trust: Bryan C. Mills
+Run-TryBot: Emmanuel Odeke
+(cherry picked from commit f0d23c9dbb2142b975fa8fb13a57213d0c15bdd1)
+Reviewed-on: https://go-review.googlesource.com/c/go/+/296530
+Trust: Ian Lance Taylor
+Run-TryBot: Ian Lance Taylor
+TryBot-Result: Go Bot
+
+Conflict:NA
+Reference:https://github.com/golang/go/commit/30357d6ef6513b18fade686a629ab8d49987260f
+
+---
+ src/internal/poll/sendfile_bsd.go | 4 ++
+ src/internal/poll/sendfile_linux.go | 3 ++
+ src/internal/poll/sendfile_solaris.go | 3 ++
+ src/net/sendfile_test.go | 64 +++++++++++++++++++++++++++
+ 4 files changed, 74 insertions(+)
+
+diff --git a/src/internal/poll/sendfile_bsd.go b/src/internal/poll/sendfile_bsd.go
+index a24e41dcaa..66005a9f5c 100644
+--- a/src/internal/poll/sendfile_bsd.go
++++ b/src/internal/poll/sendfile_bsd.go
+@@ -18,6 +18,10 @@ func SendFile(dstFD *FD, src int, pos, remain int64) (int64, error) {
+ return 0, err
+ }
+ defer dstFD.writeUnlock()
++ if err := dstFD.pd.prepareWrite(dstFD.isFile); err != nil {
++ return 0, err
++ }
++
+ dst := int(dstFD.Sysfd)
+ var written int64
+ var err error
+diff --git a/src/internal/poll/sendfile_linux.go b/src/internal/poll/sendfile_linux.go
+index d64283007d..d6442e8666 100644
+--- a/src/internal/poll/sendfile_linux.go
++++ b/src/internal/poll/sendfile_linux.go
+@@ -16,6 +16,9 @@ func SendFile(dstFD *FD, src int, remain int64) (int64, error) {
+ return 0, err
+ }
+ defer dstFD.writeUnlock()
++ if err := dstFD.pd.prepareWrite(dstFD.isFile); err != nil {
++ return 0, err
++ }
+
+ dst := int(dstFD.Sysfd)
+ var written int64
+diff --git a/src/internal/poll/sendfile_solaris.go b/src/internal/poll/sendfile_solaris.go
+index 762992e9eb..748c85131e 100644
+--- a/src/internal/poll/sendfile_solaris.go
++++ b/src/internal/poll/sendfile_solaris.go
+@@ -20,6 +20,9 @@ func SendFile(dstFD *FD, src int, pos, remain int64) (int64, error) {
+ return 0, err
+ }
+ defer dstFD.writeUnlock()
++ if err := dstFD.pd.prepareWrite(dstFD.isFile); err != nil {
++ return 0, err
++ }
+
+ dst := int(dstFD.Sysfd)
+ var written int64
+diff --git a/src/net/sendfile_test.go b/src/net/sendfile_test.go
+index 13842a1261..0e344b3649 100644
+--- a/src/net/sendfile_test.go
++++ b/src/net/sendfile_test.go
+@@ -10,6 +10,7 @@ import (
+ "bytes"
+ "crypto/sha256"
+ "encoding/hex"
++ "errors"
+ "fmt"
+ "io"
+ "io/ioutil"
+@@ -314,3 +315,66 @@ func TestSendfilePipe(t *testing.T) {
+
+ wg.Wait()
+ }
++
++// Issue 43822: tests that returns EOF when conn write timeout.
++func TestSendfileOnWriteTimeoutExceeded(t *testing.T) {
++ ln, err := newLocalListener("tcp")
++ if err != nil {
++ t.Fatal(err)
++ }
++ defer ln.Close()
++
++ errc := make(chan error, 1)
++ go func(ln Listener) (retErr error) {
++ defer func() {
++ errc <- retErr
++ close(errc)
++ }()
++
++ conn, err := ln.Accept()
++ if err != nil {
++ return err
++ }
++ defer conn.Close()
++
++ // Set the write deadline in the past(1h ago). It makes
++ // sure that it is always write timeout.
++ if err := conn.SetWriteDeadline(time.Now().Add(-1 * time.Hour)); err != nil {
++ return err
++ }
++
++ f, err := os.Open(newton)
++ if err != nil {
++ return err
++ }
++ defer f.Close()
++
++ _, err = io.Copy(conn, f)
++ if errors.Is(err, os.ErrDeadlineExceeded) {
++ return nil
++ }
++
++ if err == nil {
++ err = fmt.Errorf("expected ErrDeadlineExceeded, but got nil")
++ }
++ return err
++ }(ln)
++
++ conn, err := Dial("tcp", ln.Addr().String())
++ if err != nil {
++ t.Fatal(err)
++ }
++ defer conn.Close()
++
++ n, err := io.Copy(ioutil.Discard, conn)
++ if err != nil {
++ t.Fatalf("expected nil error, but got %v", err)
++ }
++ if n != 0 {
++ t.Fatalf("expected receive zero, but got %d byte(s)", n)
++ }
++
++ if err := <-errc; err != nil {
++ t.Fatal(err)
++ }
++}
+--
+2.27.0
+
diff --git a/0015-release-branch.go1.15-cmd-compile-do-not-assume-TST-.patch b/0015-release-branch.go1.15-cmd-compile-do-not-assume-TST-.patch
new file mode 100644
index 0000000..ab3e6da
--- /dev/null
+++ b/0015-release-branch.go1.15-cmd-compile-do-not-assume-TST-.patch
@@ -0,0 +1,1281 @@
+From d9b4ef591c2b058004545eccf10a538aa7597adb Mon Sep 17 00:00:00 2001
+From: "Jason A. Donenfeld"
+Date: Mon, 30 Nov 2020 10:41:46 +0100
+Subject: [PATCH 15/44] [release-branch.go1.15] cmd/compile: do not assume TST
+ and TEQ set V on arm
+
+These replacement rules assume that TST and TEQ set V. But TST and
+TEQ do not set V. This is a problem because instructions like LT are
+actually checking for N!=V. But with TST and TEQ not setting V, LT
+doesn't do anything meaningful. It's possible to construct trivial
+miscompilations from this, such as:
+
+ package main
+
+ var x = [4]int32{-0x7fffffff, 0x7fffffff, 2, 4}
+
+ func main() {
+ if x[0] > x[1] {
+ panic("fail 1")
+ }
+ if x[2]&x[3] < 0 {
+ panic("fail 2") // Fails here
+ }
+ }
+
+That first comparison sets V, via the CMP that subtracts the values
+causing the overflow. Then the second comparison operation thinks that
+it uses the result of TST, when it actually uses the V from CMP.
+
+Before this fix:
+
+ TST R0, R1
+ BLT loc_6C164
+
+After this fix:
+
+ TST R0, R1
+ BMI loc_6C164
+
+The BMI instruction checks the N flag, which TST sets. This commit
+fixes the issue by using [LG][TE]noov instead of vanilla [LG][TE], and
+also adds a test case for the direct issue.
+
+Updates #42876.
+Fixes #42930.
+
+Change-Id: I13c62c88d18574247ad002b671b38d2d0b0fc6fa
+Reviewed-on: https://go-review.googlesource.com/c/go/+/282432
+Trust: Jason A. Donenfeld
+Run-TryBot: Jason A. Donenfeld
+TryBot-Result: Go Bot
+Reviewed-by: Cherry Zhang
+
+Conflict:NA
+Reference:https://github.com/golang/go/commit/d9b4ef591c2b058004545eccf10a538aa7597adb
+
+---
+ src/cmd/compile/internal/ssa/gen/ARM.rules | 128 ++++-----
+ src/cmd/compile/internal/ssa/rewriteARM.go | 306 ++++++++++-----------
+ test/fixedbugs/issue42876.go | 18 ++
+ 3 files changed, 235 insertions(+), 217 deletions(-)
+ create mode 100644 test/fixedbugs/issue42876.go
+
+diff --git a/src/cmd/compile/internal/ssa/gen/ARM.rules b/src/cmd/compile/internal/ssa/gen/ARM.rules
+index ab8bd0e81e..c69084a701 100644
+--- a/src/cmd/compile/internal/ssa/gen/ARM.rules
++++ b/src/cmd/compile/internal/ssa/gen/ARM.rules
+@@ -1369,38 +1369,38 @@
+ (LE (CMPconst [0] l:(ADDshiftLLreg x y z)) yes no) && l.Uses==1 -> (LEnoov (CMNshiftLLreg x y z) yes no)
+ (LE (CMPconst [0] l:(ADDshiftRLreg x y z)) yes no) && l.Uses==1 -> (LEnoov (CMNshiftRLreg x y z) yes no)
+ (LE (CMPconst [0] l:(ADDshiftRAreg x y z)) yes no) && l.Uses==1 -> (LEnoov (CMNshiftRAreg x y z) yes no)
+-(LT (CMPconst [0] l:(AND x y)) yes no) && l.Uses==1 -> (LT (TST x y) yes no)
+-(LT (CMPconst [0] l:(ANDconst [c] x)) yes no) && l.Uses==1 -> (LT (TSTconst [c] x) yes no)
+-(LT (CMPconst [0] l:(ANDshiftLL x y [c])) yes no) && l.Uses==1 -> (LT (TSTshiftLL x y [c]) yes no)
+-(LT (CMPconst [0] l:(ANDshiftRL x y [c])) yes no) && l.Uses==1 -> (LT (TSTshiftRL x y [c]) yes no)
+-(LT (CMPconst [0] l:(ANDshiftRA x y [c])) yes no) && l.Uses==1 -> (LT (TSTshiftRA x y [c]) yes no)
+-(LT (CMPconst [0] l:(ANDshiftLLreg x y z)) yes no) && l.Uses==1 -> (LT (TSTshiftLLreg x y z) yes no)
+-(LT (CMPconst [0] l:(ANDshiftRLreg x y z)) yes no) && l.Uses==1 -> (LT (TSTshiftRLreg x y z) yes no)
+-(LT (CMPconst [0] l:(ANDshiftRAreg x y z)) yes no) && l.Uses==1 -> (LT (TSTshiftRAreg x y z) yes no)
+-(LE (CMPconst [0] l:(AND x y)) yes no) && l.Uses==1 -> (LE (TST x y) yes no)
+-(LE (CMPconst [0] l:(ANDconst [c] x)) yes no) && l.Uses==1 -> (LE (TSTconst [c] x) yes no)
+-(LE (CMPconst [0] l:(ANDshiftLL x y [c])) yes no) && l.Uses==1 -> (LE (TSTshiftLL x y [c]) yes no)
+-(LE (CMPconst [0] l:(ANDshiftRL x y [c])) yes no) && l.Uses==1 -> (LE (TSTshiftRL x y [c]) yes no)
+-(LE (CMPconst [0] l:(ANDshiftRA x y [c])) yes no) && l.Uses==1 -> (LE (TSTshiftRA x y [c]) yes no)
+-(LE (CMPconst [0] l:(ANDshiftLLreg x y z)) yes no) && l.Uses==1 -> (LE (TSTshiftLLreg x y z) yes no)
+-(LE (CMPconst [0] l:(ANDshiftRLreg x y z)) yes no) && l.Uses==1 -> (LE (TSTshiftRLreg x y z) yes no)
+-(LE (CMPconst [0] l:(ANDshiftRAreg x y z)) yes no) && l.Uses==1 -> (LE (TSTshiftRAreg x y z) yes no)
+-(LT (CMPconst [0] l:(XOR x y)) yes no) && l.Uses==1 -> (LT (TEQ x y) yes no)
+-(LT (CMPconst [0] l:(XORconst [c] x)) yes no) && l.Uses==1 -> (LT (TEQconst [c] x) yes no)
+-(LT (CMPconst [0] l:(XORshiftLL x y [c])) yes no) && l.Uses==1 -> (LT (TEQshiftLL x y [c]) yes no)
+-(LT (CMPconst [0] l:(XORshiftRL x y [c])) yes no) && l.Uses==1 -> (LT (TEQshiftRL x y [c]) yes no)
+-(LT (CMPconst [0] l:(XORshiftRA x y [c])) yes no) && l.Uses==1 -> (LT (TEQshiftRA x y [c]) yes no)
+-(LT (CMPconst [0] l:(XORshiftLLreg x y z)) yes no) && l.Uses==1 -> (LT (TEQshiftLLreg x y z) yes no)
+-(LT (CMPconst [0] l:(XORshiftRLreg x y z)) yes no) && l.Uses==1 -> (LT (TEQshiftRLreg x y z) yes no)
+-(LT (CMPconst [0] l:(XORshiftRAreg x y z)) yes no) && l.Uses==1 -> (LT (TEQshiftRAreg x y z) yes no)
+-(LE (CMPconst [0] l:(XOR x y)) yes no) && l.Uses==1 -> (LE (TEQ x y) yes no)
+-(LE (CMPconst [0] l:(XORconst [c] x)) yes no) && l.Uses==1 -> (LE (TEQconst [c] x) yes no)
+-(LE (CMPconst [0] l:(XORshiftLL x y [c])) yes no) && l.Uses==1 -> (LE (TEQshiftLL x y [c]) yes no)
+-(LE (CMPconst [0] l:(XORshiftRL x y [c])) yes no) && l.Uses==1 -> (LE (TEQshiftRL x y [c]) yes no)
+-(LE (CMPconst [0] l:(XORshiftRA x y [c])) yes no) && l.Uses==1 -> (LE (TEQshiftRA x y [c]) yes no)
+-(LE (CMPconst [0] l:(XORshiftLLreg x y z)) yes no) && l.Uses==1 -> (LE (TEQshiftLLreg x y z) yes no)
+-(LE (CMPconst [0] l:(XORshiftRLreg x y z)) yes no) && l.Uses==1 -> (LE (TEQshiftRLreg x y z) yes no)
+-(LE (CMPconst [0] l:(XORshiftRAreg x y z)) yes no) && l.Uses==1 -> (LE (TEQshiftRAreg x y z) yes no)
++(LT (CMPconst [0] l:(AND x y)) yes no) && l.Uses==1 -> (LTnoov (TST x y) yes no)
++(LT (CMPconst [0] l:(ANDconst [c] x)) yes no) && l.Uses==1 -> (LTnoov (TSTconst [c] x) yes no)
++(LT (CMPconst [0] l:(ANDshiftLL x y [c])) yes no) && l.Uses==1 -> (LTnoov (TSTshiftLL x y [c]) yes no)
++(LT (CMPconst [0] l:(ANDshiftRL x y [c])) yes no) && l.Uses==1 -> (LTnoov (TSTshiftRL x y [c]) yes no)
++(LT (CMPconst [0] l:(ANDshiftRA x y [c])) yes no) && l.Uses==1 -> (LTnoov (TSTshiftRA x y [c]) yes no)
++(LT (CMPconst [0] l:(ANDshiftLLreg x y z)) yes no) && l.Uses==1 -> (LTnoov (TSTshiftLLreg x y z) yes no)
++(LT (CMPconst [0] l:(ANDshiftRLreg x y z)) yes no) && l.Uses==1 -> (LTnoov (TSTshiftRLreg x y z) yes no)
++(LT (CMPconst [0] l:(ANDshiftRAreg x y z)) yes no) && l.Uses==1 -> (LTnoov (TSTshiftRAreg x y z) yes no)
++(LE (CMPconst [0] l:(AND x y)) yes no) && l.Uses==1 -> (LEnoov (TST x y) yes no)
++(LE (CMPconst [0] l:(ANDconst [c] x)) yes no) && l.Uses==1 -> (LEnoov (TSTconst [c] x) yes no)
++(LE (CMPconst [0] l:(ANDshiftLL x y [c])) yes no) && l.Uses==1 -> (LEnoov (TSTshiftLL x y [c]) yes no)
++(LE (CMPconst [0] l:(ANDshiftRL x y [c])) yes no) && l.Uses==1 -> (LEnoov (TSTshiftRL x y [c]) yes no)
++(LE (CMPconst [0] l:(ANDshiftRA x y [c])) yes no) && l.Uses==1 -> (LEnoov (TSTshiftRA x y [c]) yes no)
++(LE (CMPconst [0] l:(ANDshiftLLreg x y z)) yes no) && l.Uses==1 -> (LEnoov (TSTshiftLLreg x y z) yes no)
++(LE (CMPconst [0] l:(ANDshiftRLreg x y z)) yes no) && l.Uses==1 -> (LEnoov (TSTshiftRLreg x y z) yes no)
++(LE (CMPconst [0] l:(ANDshiftRAreg x y z)) yes no) && l.Uses==1 -> (LEnoov (TSTshiftRAreg x y z) yes no)
++(LT (CMPconst [0] l:(XOR x y)) yes no) && l.Uses==1 -> (LTnoov (TEQ x y) yes no)
++(LT (CMPconst [0] l:(XORconst [c] x)) yes no) && l.Uses==1 -> (LTnoov (TEQconst [c] x) yes no)
++(LT (CMPconst [0] l:(XORshiftLL x y [c])) yes no) && l.Uses==1 -> (LTnoov (TEQshiftLL x y [c]) yes no)
++(LT (CMPconst [0] l:(XORshiftRL x y [c])) yes no) && l.Uses==1 -> (LTnoov (TEQshiftRL x y [c]) yes no)
++(LT (CMPconst [0] l:(XORshiftRA x y [c])) yes no) && l.Uses==1 -> (LTnoov (TEQshiftRA x y [c]) yes no)
++(LT (CMPconst [0] l:(XORshiftLLreg x y z)) yes no) && l.Uses==1 -> (LTnoov (TEQshiftLLreg x y z) yes no)
++(LT (CMPconst [0] l:(XORshiftRLreg x y z)) yes no) && l.Uses==1 -> (LTnoov (TEQshiftRLreg x y z) yes no)
++(LT (CMPconst [0] l:(XORshiftRAreg x y z)) yes no) && l.Uses==1 -> (LTnoov (TEQshiftRAreg x y z) yes no)
++(LE (CMPconst [0] l:(XOR x y)) yes no) && l.Uses==1 -> (LEnoov (TEQ x y) yes no)
++(LE (CMPconst [0] l:(XORconst [c] x)) yes no) && l.Uses==1 -> (LEnoov (TEQconst [c] x) yes no)
++(LE (CMPconst [0] l:(XORshiftLL x y [c])) yes no) && l.Uses==1 -> (LEnoov (TEQshiftLL x y [c]) yes no)
++(LE (CMPconst [0] l:(XORshiftRL x y [c])) yes no) && l.Uses==1 -> (LEnoov (TEQshiftRL x y [c]) yes no)
++(LE (CMPconst [0] l:(XORshiftRA x y [c])) yes no) && l.Uses==1 -> (LEnoov (TEQshiftRA x y [c]) yes no)
++(LE (CMPconst [0] l:(XORshiftLLreg x y z)) yes no) && l.Uses==1 -> (LEnoov (TEQshiftLLreg x y z) yes no)
++(LE (CMPconst [0] l:(XORshiftRLreg x y z)) yes no) && l.Uses==1 -> (LEnoov (TEQshiftRLreg x y z) yes no)
++(LE (CMPconst [0] l:(XORshiftRAreg x y z)) yes no) && l.Uses==1 -> (LEnoov (TEQshiftRAreg x y z) yes no)
+ (GT (CMPconst [0] l:(SUB x y)) yes no) && l.Uses==1 -> (GTnoov (CMP x y) yes no)
+ (GT (CMPconst [0] l:(MULS x y a)) yes no) && l.Uses==1 -> (GTnoov (CMP a (MUL x y)) yes no)
+ (GT (CMPconst [0] l:(SUBconst [c] x)) yes no) && l.Uses==1 -> (GTnoov (CMPconst [c] x) yes no)
+@@ -1436,39 +1436,39 @@
+ (GE (CMPconst [0] l:(ADDshiftLLreg x y z)) yes no) && l.Uses==1 -> (GEnoov (CMNshiftLLreg x y z) yes no)
+ (GE (CMPconst [0] l:(ADDshiftRLreg x y z)) yes no) && l.Uses==1 -> (GEnoov (CMNshiftRLreg x y z) yes no)
+ (GE (CMPconst [0] l:(ADDshiftRAreg x y z)) yes no) && l.Uses==1 -> (GEnoov (CMNshiftRAreg x y z) yes no)
+-(GT (CMPconst [0] l:(AND x y)) yes no) && l.Uses==1 -> (GT (TST x y) yes no)
+ (GT (CMPconst [0] l:(MULA x y a)) yes no) && l.Uses==1 -> (GTnoov (CMN a (MUL x y)) yes no)
+-(GT (CMPconst [0] l:(ANDconst [c] x)) yes no) && l.Uses==1 -> (GT (TSTconst [c] x) yes no)
+-(GT (CMPconst [0] l:(ANDshiftLL x y [c])) yes no) && l.Uses==1 -> (GT (TSTshiftLL x y [c]) yes no)
+-(GT (CMPconst [0] l:(ANDshiftRL x y [c])) yes no) && l.Uses==1 -> (GT (TSTshiftRL x y [c]) yes no)
+-(GT (CMPconst [0] l:(ANDshiftRA x y [c])) yes no) && l.Uses==1 -> (GT (TSTshiftRA x y [c]) yes no)
+-(GT (CMPconst [0] l:(ANDshiftLLreg x y z)) yes no) && l.Uses==1 -> (GT (TSTshiftLLreg x y z) yes no)
+-(GT (CMPconst [0] l:(ANDshiftRLreg x y z)) yes no) && l.Uses==1 -> (GT (TSTshiftRLreg x y z) yes no)
+-(GT (CMPconst [0] l:(ANDshiftRAreg x y z)) yes no) && l.Uses==1 -> (GT (TSTshiftRAreg x y z) yes no)
+-(GE (CMPconst [0] l:(AND x y)) yes no) && l.Uses==1 -> (GE (TST x y) yes no)
+-(GE (CMPconst [0] l:(ANDconst [c] x)) yes no) && l.Uses==1 -> (GE (TSTconst [c] x) yes no)
+-(GE (CMPconst [0] l:(ANDshiftLL x y [c])) yes no) && l.Uses==1 -> (GE (TSTshiftLL x y [c]) yes no)
+-(GE (CMPconst [0] l:(ANDshiftRL x y [c])) yes no) && l.Uses==1 -> (GE (TSTshiftRL x y [c]) yes no)
+-(GE (CMPconst [0] l:(ANDshiftRA x y [c])) yes no) && l.Uses==1 -> (GE (TSTshiftRA x y [c]) yes no)
+-(GE (CMPconst [0] l:(ANDshiftLLreg x y z)) yes no) && l.Uses==1 -> (GE (TSTshiftLLreg x y z) yes no)
+-(GE (CMPconst [0] l:(ANDshiftRLreg x y z)) yes no) && l.Uses==1 -> (GE (TSTshiftRLreg x y z) yes no)
+-(GE (CMPconst [0] l:(ANDshiftRAreg x y z)) yes no) && l.Uses==1 -> (GE (TSTshiftRAreg x y z) yes no)
+-(GT (CMPconst [0] l:(XOR x y)) yes no) && l.Uses==1 -> (GT (TEQ x y) yes no)
+-(GT (CMPconst [0] l:(XORconst [c] x)) yes no) && l.Uses==1 -> (GT (TEQconst [c] x) yes no)
+-(GT (CMPconst [0] l:(XORshiftLL x y [c])) yes no) && l.Uses==1 -> (GT (TEQshiftLL x y [c]) yes no)
+-(GT (CMPconst [0] l:(XORshiftRL x y [c])) yes no) && l.Uses==1 -> (GT (TEQshiftRL x y [c]) yes no)
+-(GT (CMPconst [0] l:(XORshiftRA x y [c])) yes no) && l.Uses==1 -> (GT (TEQshiftRA x y [c]) yes no)
+-(GT (CMPconst [0] l:(XORshiftLLreg x y z)) yes no) && l.Uses==1 -> (GT (TEQshiftLLreg x y z) yes no)
+-(GT (CMPconst [0] l:(XORshiftRLreg x y z)) yes no) && l.Uses==1 -> (GT (TEQshiftRLreg x y z) yes no)
+-(GT (CMPconst [0] l:(XORshiftRAreg x y z)) yes no) && l.Uses==1 -> (GT (TEQshiftRAreg x y z) yes no)
+-(GE (CMPconst [0] l:(XOR x y)) yes no) && l.Uses==1 -> (GE (TEQ x y) yes no)
+-(GE (CMPconst [0] l:(XORconst [c] x)) yes no) && l.Uses==1 -> (GE (TEQconst [c] x) yes no)
+-(GE (CMPconst [0] l:(XORshiftLL x y [c])) yes no) && l.Uses==1 -> (GE (TEQshiftLL x y [c]) yes no)
+-(GE (CMPconst [0] l:(XORshiftRL x y [c])) yes no) && l.Uses==1 -> (GE (TEQshiftRL x y [c]) yes no)
+-(GE (CMPconst [0] l:(XORshiftRA x y [c])) yes no) && l.Uses==1 -> (GE (TEQshiftRA x y [c]) yes no)
+-(GE (CMPconst [0] l:(XORshiftLLreg x y z)) yes no) && l.Uses==1 -> (GE (TEQshiftLLreg x y z) yes no)
+-(GE (CMPconst [0] l:(XORshiftRLreg x y z)) yes no) && l.Uses==1 -> (GE (TEQshiftRLreg x y z) yes no)
+-(GE (CMPconst [0] l:(XORshiftRAreg x y z)) yes no) && l.Uses==1 -> (GE (TEQshiftRAreg x y z) yes no)
++(GT (CMPconst [0] l:(AND x y)) yes no) && l.Uses==1 -> (GTnoov (TST x y) yes no)
++(GT (CMPconst [0] l:(ANDconst [c] x)) yes no) && l.Uses==1 -> (GTnoov (TSTconst [c] x) yes no)
++(GT (CMPconst [0] l:(ANDshiftLL x y [c])) yes no) && l.Uses==1 -> (GTnoov (TSTshiftLL x y [c]) yes no)
++(GT (CMPconst [0] l:(ANDshiftRL x y [c])) yes no) && l.Uses==1 -> (GTnoov (TSTshiftRL x y [c]) yes no)
++(GT (CMPconst [0] l:(ANDshiftRA x y [c])) yes no) && l.Uses==1 -> (GTnoov (TSTshiftRA x y [c]) yes no)
++(GT (CMPconst [0] l:(ANDshiftLLreg x y z)) yes no) && l.Uses==1 -> (GTnoov (TSTshiftLLreg x y z) yes no)
++(GT (CMPconst [0] l:(ANDshiftRLreg x y z)) yes no) && l.Uses==1 -> (GTnoov (TSTshiftRLreg x y z) yes no)
++(GT (CMPconst [0] l:(ANDshiftRAreg x y z)) yes no) && l.Uses==1 -> (GTnoov (TSTshiftRAreg x y z) yes no)
++(GE (CMPconst [0] l:(AND x y)) yes no) && l.Uses==1 -> (GEnoov (TST x y) yes no)
++(GE (CMPconst [0] l:(ANDconst [c] x)) yes no) && l.Uses==1 -> (GEnoov (TSTconst [c] x) yes no)
++(GE (CMPconst [0] l:(ANDshiftLL x y [c])) yes no) && l.Uses==1 -> (GEnoov (TSTshiftLL x y [c]) yes no)
++(GE (CMPconst [0] l:(ANDshiftRL x y [c])) yes no) && l.Uses==1 -> (GEnoov (TSTshiftRL x y [c]) yes no)
++(GE (CMPconst [0] l:(ANDshiftRA x y [c])) yes no) && l.Uses==1 -> (GEnoov (TSTshiftRA x y [c]) yes no)
++(GE (CMPconst [0] l:(ANDshiftLLreg x y z)) yes no) && l.Uses==1 -> (GEnoov (TSTshiftLLreg x y z) yes no)
++(GE (CMPconst [0] l:(ANDshiftRLreg x y z)) yes no) && l.Uses==1 -> (GEnoov (TSTshiftRLreg x y z) yes no)
++(GE (CMPconst [0] l:(ANDshiftRAreg x y z)) yes no) && l.Uses==1 -> (GEnoov (TSTshiftRAreg x y z) yes no)
++(GT (CMPconst [0] l:(XOR x y)) yes no) && l.Uses==1 -> (GTnoov (TEQ x y) yes no)
++(GT (CMPconst [0] l:(XORconst [c] x)) yes no) && l.Uses==1 -> (GTnoov (TEQconst [c] x) yes no)
++(GT (CMPconst [0] l:(XORshiftLL x y [c])) yes no) && l.Uses==1 -> (GTnoov (TEQshiftLL x y [c]) yes no)
++(GT (CMPconst [0] l:(XORshiftRL x y [c])) yes no) && l.Uses==1 -> (GTnoov (TEQshiftRL x y [c]) yes no)
++(GT (CMPconst [0] l:(XORshiftRA x y [c])) yes no) && l.Uses==1 -> (GTnoov (TEQshiftRA x y [c]) yes no)
++(GT (CMPconst [0] l:(XORshiftLLreg x y z)) yes no) && l.Uses==1 -> (GTnoov (TEQshiftLLreg x y z) yes no)
++(GT (CMPconst [0] l:(XORshiftRLreg x y z)) yes no) && l.Uses==1 -> (GTnoov (TEQshiftRLreg x y z) yes no)
++(GT (CMPconst [0] l:(XORshiftRAreg x y z)) yes no) && l.Uses==1 -> (GTnoov (TEQshiftRAreg x y z) yes no)
++(GE (CMPconst [0] l:(XOR x y)) yes no) && l.Uses==1 -> (GEnoov (TEQ x y) yes no)
++(GE (CMPconst [0] l:(XORconst [c] x)) yes no) && l.Uses==1 -> (GEnoov (TEQconst [c] x) yes no)
++(GE (CMPconst [0] l:(XORshiftLL x y [c])) yes no) && l.Uses==1 -> (GEnoov (TEQshiftLL x y [c]) yes no)
++(GE (CMPconst [0] l:(XORshiftRL x y [c])) yes no) && l.Uses==1 -> (GEnoov (TEQshiftRL x y [c]) yes no)
++(GE (CMPconst [0] l:(XORshiftRA x y [c])) yes no) && l.Uses==1 -> (GEnoov (TEQshiftRA x y [c]) yes no)
++(GE (CMPconst [0] l:(XORshiftLLreg x y z)) yes no) && l.Uses==1 -> (GEnoov (TEQshiftLLreg x y z) yes no)
++(GE (CMPconst [0] l:(XORshiftRLreg x y z)) yes no) && l.Uses==1 -> (GEnoov (TEQshiftRLreg x y z) yes no)
++(GE (CMPconst [0] l:(XORshiftRAreg x y z)) yes no) && l.Uses==1 -> (GEnoov (TEQshiftRAreg x y z) yes no)
+
+ (MOVBUload [off] {sym} (SB) _) && symIsRO(sym) -> (MOVWconst [int64(read8(sym, off))])
+ (MOVHUload [off] {sym} (SB) _) && symIsRO(sym) -> (MOVWconst [int64(read16(sym, off, config.ctxt.Arch.ByteOrder))])
+diff --git a/src/cmd/compile/internal/ssa/rewriteARM.go b/src/cmd/compile/internal/ssa/rewriteARM.go
+index f55e542505..07653b78f8 100644
+--- a/src/cmd/compile/internal/ssa/rewriteARM.go
++++ b/src/cmd/compile/internal/ssa/rewriteARM.go
+@@ -17278,7 +17278,7 @@ func rewriteBlockARM(b *Block) bool {
+ }
+ // match: (GE (CMPconst [0] l:(AND x y)) yes no)
+ // cond: l.Uses==1
+- // result: (GE (TST x y) yes no)
++ // result: (GEnoov (TST x y) yes no)
+ for b.Controls[0].Op == OpARMCMPconst {
+ v_0 := b.Controls[0]
+ if v_0.AuxInt != 0 {
+@@ -17299,14 +17299,14 @@ func rewriteBlockARM(b *Block) bool {
+ }
+ v0 := b.NewValue0(v_0.Pos, OpARMTST, types.TypeFlags)
+ v0.AddArg2(x, y)
+- b.resetWithControl(BlockARMGE, v0)
++ b.resetWithControl(BlockARMGEnoov, v0)
+ return true
+ }
+ break
+ }
+ // match: (GE (CMPconst [0] l:(ANDconst [c] x)) yes no)
+ // cond: l.Uses==1
+- // result: (GE (TSTconst [c] x) yes no)
++ // result: (GEnoov (TSTconst [c] x) yes no)
+ for b.Controls[0].Op == OpARMCMPconst {
+ v_0 := b.Controls[0]
+ if v_0.AuxInt != 0 {
+@@ -17324,12 +17324,12 @@ func rewriteBlockARM(b *Block) bool {
+ v0 := b.NewValue0(v_0.Pos, OpARMTSTconst, types.TypeFlags)
+ v0.AuxInt = c
+ v0.AddArg(x)
+- b.resetWithControl(BlockARMGE, v0)
++ b.resetWithControl(BlockARMGEnoov, v0)
+ return true
+ }
+ // match: (GE (CMPconst [0] l:(ANDshiftLL x y [c])) yes no)
+ // cond: l.Uses==1
+- // result: (GE (TSTshiftLL x y [c]) yes no)
++ // result: (GEnoov (TSTshiftLL x y [c]) yes no)
+ for b.Controls[0].Op == OpARMCMPconst {
+ v_0 := b.Controls[0]
+ if v_0.AuxInt != 0 {
+@@ -17348,12 +17348,12 @@ func rewriteBlockARM(b *Block) bool {
+ v0 := b.NewValue0(v_0.Pos, OpARMTSTshiftLL, types.TypeFlags)
+ v0.AuxInt = c
+ v0.AddArg2(x, y)
+- b.resetWithControl(BlockARMGE, v0)
++ b.resetWithControl(BlockARMGEnoov, v0)
+ return true
+ }
+ // match: (GE (CMPconst [0] l:(ANDshiftRL x y [c])) yes no)
+ // cond: l.Uses==1
+- // result: (GE (TSTshiftRL x y [c]) yes no)
++ // result: (GEnoov (TSTshiftRL x y [c]) yes no)
+ for b.Controls[0].Op == OpARMCMPconst {
+ v_0 := b.Controls[0]
+ if v_0.AuxInt != 0 {
+@@ -17372,12 +17372,12 @@ func rewriteBlockARM(b *Block) bool {
+ v0 := b.NewValue0(v_0.Pos, OpARMTSTshiftRL, types.TypeFlags)
+ v0.AuxInt = c
+ v0.AddArg2(x, y)
+- b.resetWithControl(BlockARMGE, v0)
++ b.resetWithControl(BlockARMGEnoov, v0)
+ return true
+ }
+ // match: (GE (CMPconst [0] l:(ANDshiftRA x y [c])) yes no)
+ // cond: l.Uses==1
+- // result: (GE (TSTshiftRA x y [c]) yes no)
++ // result: (GEnoov (TSTshiftRA x y [c]) yes no)
+ for b.Controls[0].Op == OpARMCMPconst {
+ v_0 := b.Controls[0]
+ if v_0.AuxInt != 0 {
+@@ -17396,12 +17396,12 @@ func rewriteBlockARM(b *Block) bool {
+ v0 := b.NewValue0(v_0.Pos, OpARMTSTshiftRA, types.TypeFlags)
+ v0.AuxInt = c
+ v0.AddArg2(x, y)
+- b.resetWithControl(BlockARMGE, v0)
++ b.resetWithControl(BlockARMGEnoov, v0)
+ return true
+ }
+ // match: (GE (CMPconst [0] l:(ANDshiftLLreg x y z)) yes no)
+ // cond: l.Uses==1
+- // result: (GE (TSTshiftLLreg x y z) yes no)
++ // result: (GEnoov (TSTshiftLLreg x y z) yes no)
+ for b.Controls[0].Op == OpARMCMPconst {
+ v_0 := b.Controls[0]
+ if v_0.AuxInt != 0 {
+@@ -17419,12 +17419,12 @@ func rewriteBlockARM(b *Block) bool {
+ }
+ v0 := b.NewValue0(v_0.Pos, OpARMTSTshiftLLreg, types.TypeFlags)
+ v0.AddArg3(x, y, z)
+- b.resetWithControl(BlockARMGE, v0)
++ b.resetWithControl(BlockARMGEnoov, v0)
+ return true
+ }
+ // match: (GE (CMPconst [0] l:(ANDshiftRLreg x y z)) yes no)
+ // cond: l.Uses==1
+- // result: (GE (TSTshiftRLreg x y z) yes no)
++ // result: (GEnoov (TSTshiftRLreg x y z) yes no)
+ for b.Controls[0].Op == OpARMCMPconst {
+ v_0 := b.Controls[0]
+ if v_0.AuxInt != 0 {
+@@ -17442,12 +17442,12 @@ func rewriteBlockARM(b *Block) bool {
+ }
+ v0 := b.NewValue0(v_0.Pos, OpARMTSTshiftRLreg, types.TypeFlags)
+ v0.AddArg3(x, y, z)
+- b.resetWithControl(BlockARMGE, v0)
++ b.resetWithControl(BlockARMGEnoov, v0)
+ return true
+ }
+ // match: (GE (CMPconst [0] l:(ANDshiftRAreg x y z)) yes no)
+ // cond: l.Uses==1
+- // result: (GE (TSTshiftRAreg x y z) yes no)
++ // result: (GEnoov (TSTshiftRAreg x y z) yes no)
+ for b.Controls[0].Op == OpARMCMPconst {
+ v_0 := b.Controls[0]
+ if v_0.AuxInt != 0 {
+@@ -17465,12 +17465,12 @@ func rewriteBlockARM(b *Block) bool {
+ }
+ v0 := b.NewValue0(v_0.Pos, OpARMTSTshiftRAreg, types.TypeFlags)
+ v0.AddArg3(x, y, z)
+- b.resetWithControl(BlockARMGE, v0)
++ b.resetWithControl(BlockARMGEnoov, v0)
+ return true
+ }
+ // match: (GE (CMPconst [0] l:(XOR x y)) yes no)
+ // cond: l.Uses==1
+- // result: (GE (TEQ x y) yes no)
++ // result: (GEnoov (TEQ x y) yes no)
+ for b.Controls[0].Op == OpARMCMPconst {
+ v_0 := b.Controls[0]
+ if v_0.AuxInt != 0 {
+@@ -17491,14 +17491,14 @@ func rewriteBlockARM(b *Block) bool {
+ }
+ v0 := b.NewValue0(v_0.Pos, OpARMTEQ, types.TypeFlags)
+ v0.AddArg2(x, y)
+- b.resetWithControl(BlockARMGE, v0)
++ b.resetWithControl(BlockARMGEnoov, v0)
+ return true
+ }
+ break
+ }
+ // match: (GE (CMPconst [0] l:(XORconst [c] x)) yes no)
+ // cond: l.Uses==1
+- // result: (GE (TEQconst [c] x) yes no)
++ // result: (GEnoov (TEQconst [c] x) yes no)
+ for b.Controls[0].Op == OpARMCMPconst {
+ v_0 := b.Controls[0]
+ if v_0.AuxInt != 0 {
+@@ -17516,12 +17516,12 @@ func rewriteBlockARM(b *Block) bool {
+ v0 := b.NewValue0(v_0.Pos, OpARMTEQconst, types.TypeFlags)
+ v0.AuxInt = c
+ v0.AddArg(x)
+- b.resetWithControl(BlockARMGE, v0)
++ b.resetWithControl(BlockARMGEnoov, v0)
+ return true
+ }
+ // match: (GE (CMPconst [0] l:(XORshiftLL x y [c])) yes no)
+ // cond: l.Uses==1
+- // result: (GE (TEQshiftLL x y [c]) yes no)
++ // result: (GEnoov (TEQshiftLL x y [c]) yes no)
+ for b.Controls[0].Op == OpARMCMPconst {
+ v_0 := b.Controls[0]
+ if v_0.AuxInt != 0 {
+@@ -17540,12 +17540,12 @@ func rewriteBlockARM(b *Block) bool {
+ v0 := b.NewValue0(v_0.Pos, OpARMTEQshiftLL, types.TypeFlags)
+ v0.AuxInt = c
+ v0.AddArg2(x, y)
+- b.resetWithControl(BlockARMGE, v0)
++ b.resetWithControl(BlockARMGEnoov, v0)
+ return true
+ }
+ // match: (GE (CMPconst [0] l:(XORshiftRL x y [c])) yes no)
+ // cond: l.Uses==1
+- // result: (GE (TEQshiftRL x y [c]) yes no)
++ // result: (GEnoov (TEQshiftRL x y [c]) yes no)
+ for b.Controls[0].Op == OpARMCMPconst {
+ v_0 := b.Controls[0]
+ if v_0.AuxInt != 0 {
+@@ -17564,12 +17564,12 @@ func rewriteBlockARM(b *Block) bool {
+ v0 := b.NewValue0(v_0.Pos, OpARMTEQshiftRL, types.TypeFlags)
+ v0.AuxInt = c
+ v0.AddArg2(x, y)
+- b.resetWithControl(BlockARMGE, v0)
++ b.resetWithControl(BlockARMGEnoov, v0)
+ return true
+ }
+ // match: (GE (CMPconst [0] l:(XORshiftRA x y [c])) yes no)
+ // cond: l.Uses==1
+- // result: (GE (TEQshiftRA x y [c]) yes no)
++ // result: (GEnoov (TEQshiftRA x y [c]) yes no)
+ for b.Controls[0].Op == OpARMCMPconst {
+ v_0 := b.Controls[0]
+ if v_0.AuxInt != 0 {
+@@ -17588,12 +17588,12 @@ func rewriteBlockARM(b *Block) bool {
+ v0 := b.NewValue0(v_0.Pos, OpARMTEQshiftRA, types.TypeFlags)
+ v0.AuxInt = c
+ v0.AddArg2(x, y)
+- b.resetWithControl(BlockARMGE, v0)
++ b.resetWithControl(BlockARMGEnoov, v0)
+ return true
+ }
+ // match: (GE (CMPconst [0] l:(XORshiftLLreg x y z)) yes no)
+ // cond: l.Uses==1
+- // result: (GE (TEQshiftLLreg x y z) yes no)
++ // result: (GEnoov (TEQshiftLLreg x y z) yes no)
+ for b.Controls[0].Op == OpARMCMPconst {
+ v_0 := b.Controls[0]
+ if v_0.AuxInt != 0 {
+@@ -17611,12 +17611,12 @@ func rewriteBlockARM(b *Block) bool {
+ }
+ v0 := b.NewValue0(v_0.Pos, OpARMTEQshiftLLreg, types.TypeFlags)
+ v0.AddArg3(x, y, z)
+- b.resetWithControl(BlockARMGE, v0)
++ b.resetWithControl(BlockARMGEnoov, v0)
+ return true
+ }
+ // match: (GE (CMPconst [0] l:(XORshiftRLreg x y z)) yes no)
+ // cond: l.Uses==1
+- // result: (GE (TEQshiftRLreg x y z) yes no)
++ // result: (GEnoov (TEQshiftRLreg x y z) yes no)
+ for b.Controls[0].Op == OpARMCMPconst {
+ v_0 := b.Controls[0]
+ if v_0.AuxInt != 0 {
+@@ -17634,12 +17634,12 @@ func rewriteBlockARM(b *Block) bool {
+ }
+ v0 := b.NewValue0(v_0.Pos, OpARMTEQshiftRLreg, types.TypeFlags)
+ v0.AddArg3(x, y, z)
+- b.resetWithControl(BlockARMGE, v0)
++ b.resetWithControl(BlockARMGEnoov, v0)
+ return true
+ }
+ // match: (GE (CMPconst [0] l:(XORshiftRAreg x y z)) yes no)
+ // cond: l.Uses==1
+- // result: (GE (TEQshiftRAreg x y z) yes no)
++ // result: (GEnoov (TEQshiftRAreg x y z) yes no)
+ for b.Controls[0].Op == OpARMCMPconst {
+ v_0 := b.Controls[0]
+ if v_0.AuxInt != 0 {
+@@ -17657,7 +17657,7 @@ func rewriteBlockARM(b *Block) bool {
+ }
+ v0 := b.NewValue0(v_0.Pos, OpARMTEQshiftRAreg, types.TypeFlags)
+ v0.AddArg3(x, y, z)
+- b.resetWithControl(BlockARMGE, v0)
++ b.resetWithControl(BlockARMGEnoov, v0)
+ return true
+ }
+ case BlockARMGEnoov:
+@@ -18131,9 +18131,34 @@ func rewriteBlockARM(b *Block) bool {
+ b.resetWithControl(BlockARMGTnoov, v0)
+ return true
+ }
++ // match: (GT (CMPconst [0] l:(MULA x y a)) yes no)
++ // cond: l.Uses==1
++ // result: (GTnoov (CMN a (MUL x y)) yes no)
++ for b.Controls[0].Op == OpARMCMPconst {
++ v_0 := b.Controls[0]
++ if v_0.AuxInt != 0 {
++ break
++ }
++ l := v_0.Args[0]
++ if l.Op != OpARMMULA {
++ break
++ }
++ a := l.Args[2]
++ x := l.Args[0]
++ y := l.Args[1]
++ if !(l.Uses == 1) {
++ break
++ }
++ v0 := b.NewValue0(v_0.Pos, OpARMCMN, types.TypeFlags)
++ v1 := b.NewValue0(v_0.Pos, OpARMMUL, x.Type)
++ v1.AddArg2(x, y)
++ v0.AddArg2(a, v1)
++ b.resetWithControl(BlockARMGTnoov, v0)
++ return true
++ }
+ // match: (GT (CMPconst [0] l:(AND x y)) yes no)
+ // cond: l.Uses==1
+- // result: (GT (TST x y) yes no)
++ // result: (GTnoov (TST x y) yes no)
+ for b.Controls[0].Op == OpARMCMPconst {
+ v_0 := b.Controls[0]
+ if v_0.AuxInt != 0 {
+@@ -18154,39 +18179,14 @@ func rewriteBlockARM(b *Block) bool {
+ }
+ v0 := b.NewValue0(v_0.Pos, OpARMTST, types.TypeFlags)
+ v0.AddArg2(x, y)
+- b.resetWithControl(BlockARMGT, v0)
++ b.resetWithControl(BlockARMGTnoov, v0)
+ return true
+ }
+ break
+ }
+- // match: (GT (CMPconst [0] l:(MULA x y a)) yes no)
+- // cond: l.Uses==1
+- // result: (GTnoov (CMN a (MUL x y)) yes no)
+- for b.Controls[0].Op == OpARMCMPconst {
+- v_0 := b.Controls[0]
+- if v_0.AuxInt != 0 {
+- break
+- }
+- l := v_0.Args[0]
+- if l.Op != OpARMMULA {
+- break
+- }
+- a := l.Args[2]
+- x := l.Args[0]
+- y := l.Args[1]
+- if !(l.Uses == 1) {
+- break
+- }
+- v0 := b.NewValue0(v_0.Pos, OpARMCMN, types.TypeFlags)
+- v1 := b.NewValue0(v_0.Pos, OpARMMUL, x.Type)
+- v1.AddArg2(x, y)
+- v0.AddArg2(a, v1)
+- b.resetWithControl(BlockARMGTnoov, v0)
+- return true
+- }
+ // match: (GT (CMPconst [0] l:(ANDconst [c] x)) yes no)
+ // cond: l.Uses==1
+- // result: (GT (TSTconst [c] x) yes no)
++ // result: (GTnoov (TSTconst [c] x) yes no)
+ for b.Controls[0].Op == OpARMCMPconst {
+ v_0 := b.Controls[0]
+ if v_0.AuxInt != 0 {
+@@ -18204,12 +18204,12 @@ func rewriteBlockARM(b *Block) bool {
+ v0 := b.NewValue0(v_0.Pos, OpARMTSTconst, types.TypeFlags)
+ v0.AuxInt = c
+ v0.AddArg(x)
+- b.resetWithControl(BlockARMGT, v0)
++ b.resetWithControl(BlockARMGTnoov, v0)
+ return true
+ }
+ // match: (GT (CMPconst [0] l:(ANDshiftLL x y [c])) yes no)
+ // cond: l.Uses==1
+- // result: (GT (TSTshiftLL x y [c]) yes no)
++ // result: (GTnoov (TSTshiftLL x y [c]) yes no)
+ for b.Controls[0].Op == OpARMCMPconst {
+ v_0 := b.Controls[0]
+ if v_0.AuxInt != 0 {
+@@ -18228,12 +18228,12 @@ func rewriteBlockARM(b *Block) bool {
+ v0 := b.NewValue0(v_0.Pos, OpARMTSTshiftLL, types.TypeFlags)
+ v0.AuxInt = c
+ v0.AddArg2(x, y)
+- b.resetWithControl(BlockARMGT, v0)
++ b.resetWithControl(BlockARMGTnoov, v0)
+ return true
+ }
+ // match: (GT (CMPconst [0] l:(ANDshiftRL x y [c])) yes no)
+ // cond: l.Uses==1
+- // result: (GT (TSTshiftRL x y [c]) yes no)
++ // result: (GTnoov (TSTshiftRL x y [c]) yes no)
+ for b.Controls[0].Op == OpARMCMPconst {
+ v_0 := b.Controls[0]
+ if v_0.AuxInt != 0 {
+@@ -18252,12 +18252,12 @@ func rewriteBlockARM(b *Block) bool {
+ v0 := b.NewValue0(v_0.Pos, OpARMTSTshiftRL, types.TypeFlags)
+ v0.AuxInt = c
+ v0.AddArg2(x, y)
+- b.resetWithControl(BlockARMGT, v0)
++ b.resetWithControl(BlockARMGTnoov, v0)
+ return true
+ }
+ // match: (GT (CMPconst [0] l:(ANDshiftRA x y [c])) yes no)
+ // cond: l.Uses==1
+- // result: (GT (TSTshiftRA x y [c]) yes no)
++ // result: (GTnoov (TSTshiftRA x y [c]) yes no)
+ for b.Controls[0].Op == OpARMCMPconst {
+ v_0 := b.Controls[0]
+ if v_0.AuxInt != 0 {
+@@ -18276,12 +18276,12 @@ func rewriteBlockARM(b *Block) bool {
+ v0 := b.NewValue0(v_0.Pos, OpARMTSTshiftRA, types.TypeFlags)
+ v0.AuxInt = c
+ v0.AddArg2(x, y)
+- b.resetWithControl(BlockARMGT, v0)
++ b.resetWithControl(BlockARMGTnoov, v0)
+ return true
+ }
+ // match: (GT (CMPconst [0] l:(ANDshiftLLreg x y z)) yes no)
+ // cond: l.Uses==1
+- // result: (GT (TSTshiftLLreg x y z) yes no)
++ // result: (GTnoov (TSTshiftLLreg x y z) yes no)
+ for b.Controls[0].Op == OpARMCMPconst {
+ v_0 := b.Controls[0]
+ if v_0.AuxInt != 0 {
+@@ -18299,12 +18299,12 @@ func rewriteBlockARM(b *Block) bool {
+ }
+ v0 := b.NewValue0(v_0.Pos, OpARMTSTshiftLLreg, types.TypeFlags)
+ v0.AddArg3(x, y, z)
+- b.resetWithControl(BlockARMGT, v0)
++ b.resetWithControl(BlockARMGTnoov, v0)
+ return true
+ }
+ // match: (GT (CMPconst [0] l:(ANDshiftRLreg x y z)) yes no)
+ // cond: l.Uses==1
+- // result: (GT (TSTshiftRLreg x y z) yes no)
++ // result: (GTnoov (TSTshiftRLreg x y z) yes no)
+ for b.Controls[0].Op == OpARMCMPconst {
+ v_0 := b.Controls[0]
+ if v_0.AuxInt != 0 {
+@@ -18322,12 +18322,12 @@ func rewriteBlockARM(b *Block) bool {
+ }
+ v0 := b.NewValue0(v_0.Pos, OpARMTSTshiftRLreg, types.TypeFlags)
+ v0.AddArg3(x, y, z)
+- b.resetWithControl(BlockARMGT, v0)
++ b.resetWithControl(BlockARMGTnoov, v0)
+ return true
+ }
+ // match: (GT (CMPconst [0] l:(ANDshiftRAreg x y z)) yes no)
+ // cond: l.Uses==1
+- // result: (GT (TSTshiftRAreg x y z) yes no)
++ // result: (GTnoov (TSTshiftRAreg x y z) yes no)
+ for b.Controls[0].Op == OpARMCMPconst {
+ v_0 := b.Controls[0]
+ if v_0.AuxInt != 0 {
+@@ -18345,12 +18345,12 @@ func rewriteBlockARM(b *Block) bool {
+ }
+ v0 := b.NewValue0(v_0.Pos, OpARMTSTshiftRAreg, types.TypeFlags)
+ v0.AddArg3(x, y, z)
+- b.resetWithControl(BlockARMGT, v0)
++ b.resetWithControl(BlockARMGTnoov, v0)
+ return true
+ }
+ // match: (GT (CMPconst [0] l:(XOR x y)) yes no)
+ // cond: l.Uses==1
+- // result: (GT (TEQ x y) yes no)
++ // result: (GTnoov (TEQ x y) yes no)
+ for b.Controls[0].Op == OpARMCMPconst {
+ v_0 := b.Controls[0]
+ if v_0.AuxInt != 0 {
+@@ -18371,14 +18371,14 @@ func rewriteBlockARM(b *Block) bool {
+ }
+ v0 := b.NewValue0(v_0.Pos, OpARMTEQ, types.TypeFlags)
+ v0.AddArg2(x, y)
+- b.resetWithControl(BlockARMGT, v0)
++ b.resetWithControl(BlockARMGTnoov, v0)
+ return true
+ }
+ break
+ }
+ // match: (GT (CMPconst [0] l:(XORconst [c] x)) yes no)
+ // cond: l.Uses==1
+- // result: (GT (TEQconst [c] x) yes no)
++ // result: (GTnoov (TEQconst [c] x) yes no)
+ for b.Controls[0].Op == OpARMCMPconst {
+ v_0 := b.Controls[0]
+ if v_0.AuxInt != 0 {
+@@ -18396,12 +18396,12 @@ func rewriteBlockARM(b *Block) bool {
+ v0 := b.NewValue0(v_0.Pos, OpARMTEQconst, types.TypeFlags)
+ v0.AuxInt = c
+ v0.AddArg(x)
+- b.resetWithControl(BlockARMGT, v0)
++ b.resetWithControl(BlockARMGTnoov, v0)
+ return true
+ }
+ // match: (GT (CMPconst [0] l:(XORshiftLL x y [c])) yes no)
+ // cond: l.Uses==1
+- // result: (GT (TEQshiftLL x y [c]) yes no)
++ // result: (GTnoov (TEQshiftLL x y [c]) yes no)
+ for b.Controls[0].Op == OpARMCMPconst {
+ v_0 := b.Controls[0]
+ if v_0.AuxInt != 0 {
+@@ -18420,12 +18420,12 @@ func rewriteBlockARM(b *Block) bool {
+ v0 := b.NewValue0(v_0.Pos, OpARMTEQshiftLL, types.TypeFlags)
+ v0.AuxInt = c
+ v0.AddArg2(x, y)
+- b.resetWithControl(BlockARMGT, v0)
++ b.resetWithControl(BlockARMGTnoov, v0)
+ return true
+ }
+ // match: (GT (CMPconst [0] l:(XORshiftRL x y [c])) yes no)
+ // cond: l.Uses==1
+- // result: (GT (TEQshiftRL x y [c]) yes no)
++ // result: (GTnoov (TEQshiftRL x y [c]) yes no)
+ for b.Controls[0].Op == OpARMCMPconst {
+ v_0 := b.Controls[0]
+ if v_0.AuxInt != 0 {
+@@ -18444,12 +18444,12 @@ func rewriteBlockARM(b *Block) bool {
+ v0 := b.NewValue0(v_0.Pos, OpARMTEQshiftRL, types.TypeFlags)
+ v0.AuxInt = c
+ v0.AddArg2(x, y)
+- b.resetWithControl(BlockARMGT, v0)
++ b.resetWithControl(BlockARMGTnoov, v0)
+ return true
+ }
+ // match: (GT (CMPconst [0] l:(XORshiftRA x y [c])) yes no)
+ // cond: l.Uses==1
+- // result: (GT (TEQshiftRA x y [c]) yes no)
++ // result: (GTnoov (TEQshiftRA x y [c]) yes no)
+ for b.Controls[0].Op == OpARMCMPconst {
+ v_0 := b.Controls[0]
+ if v_0.AuxInt != 0 {
+@@ -18468,12 +18468,12 @@ func rewriteBlockARM(b *Block) bool {
+ v0 := b.NewValue0(v_0.Pos, OpARMTEQshiftRA, types.TypeFlags)
+ v0.AuxInt = c
+ v0.AddArg2(x, y)
+- b.resetWithControl(BlockARMGT, v0)
++ b.resetWithControl(BlockARMGTnoov, v0)
+ return true
+ }
+ // match: (GT (CMPconst [0] l:(XORshiftLLreg x y z)) yes no)
+ // cond: l.Uses==1
+- // result: (GT (TEQshiftLLreg x y z) yes no)
++ // result: (GTnoov (TEQshiftLLreg x y z) yes no)
+ for b.Controls[0].Op == OpARMCMPconst {
+ v_0 := b.Controls[0]
+ if v_0.AuxInt != 0 {
+@@ -18491,12 +18491,12 @@ func rewriteBlockARM(b *Block) bool {
+ }
+ v0 := b.NewValue0(v_0.Pos, OpARMTEQshiftLLreg, types.TypeFlags)
+ v0.AddArg3(x, y, z)
+- b.resetWithControl(BlockARMGT, v0)
++ b.resetWithControl(BlockARMGTnoov, v0)
+ return true
+ }
+ // match: (GT (CMPconst [0] l:(XORshiftRLreg x y z)) yes no)
+ // cond: l.Uses==1
+- // result: (GT (TEQshiftRLreg x y z) yes no)
++ // result: (GTnoov (TEQshiftRLreg x y z) yes no)
+ for b.Controls[0].Op == OpARMCMPconst {
+ v_0 := b.Controls[0]
+ if v_0.AuxInt != 0 {
+@@ -18514,12 +18514,12 @@ func rewriteBlockARM(b *Block) bool {
+ }
+ v0 := b.NewValue0(v_0.Pos, OpARMTEQshiftRLreg, types.TypeFlags)
+ v0.AddArg3(x, y, z)
+- b.resetWithControl(BlockARMGT, v0)
++ b.resetWithControl(BlockARMGTnoov, v0)
+ return true
+ }
+ // match: (GT (CMPconst [0] l:(XORshiftRAreg x y z)) yes no)
+ // cond: l.Uses==1
+- // result: (GT (TEQshiftRAreg x y z) yes no)
++ // result: (GTnoov (TEQshiftRAreg x y z) yes no)
+ for b.Controls[0].Op == OpARMCMPconst {
+ v_0 := b.Controls[0]
+ if v_0.AuxInt != 0 {
+@@ -18537,7 +18537,7 @@ func rewriteBlockARM(b *Block) bool {
+ }
+ v0 := b.NewValue0(v_0.Pos, OpARMTEQshiftRAreg, types.TypeFlags)
+ v0.AddArg3(x, y, z)
+- b.resetWithControl(BlockARMGT, v0)
++ b.resetWithControl(BlockARMGTnoov, v0)
+ return true
+ }
+ case BlockARMGTnoov:
+@@ -19129,7 +19129,7 @@ func rewriteBlockARM(b *Block) bool {
+ }
+ // match: (LE (CMPconst [0] l:(AND x y)) yes no)
+ // cond: l.Uses==1
+- // result: (LE (TST x y) yes no)
++ // result: (LEnoov (TST x y) yes no)
+ for b.Controls[0].Op == OpARMCMPconst {
+ v_0 := b.Controls[0]
+ if v_0.AuxInt != 0 {
+@@ -19150,14 +19150,14 @@ func rewriteBlockARM(b *Block) bool {
+ }
+ v0 := b.NewValue0(v_0.Pos, OpARMTST, types.TypeFlags)
+ v0.AddArg2(x, y)
+- b.resetWithControl(BlockARMLE, v0)
++ b.resetWithControl(BlockARMLEnoov, v0)
+ return true
+ }
+ break
+ }
+ // match: (LE (CMPconst [0] l:(ANDconst [c] x)) yes no)
+ // cond: l.Uses==1
+- // result: (LE (TSTconst [c] x) yes no)
++ // result: (LEnoov (TSTconst [c] x) yes no)
+ for b.Controls[0].Op == OpARMCMPconst {
+ v_0 := b.Controls[0]
+ if v_0.AuxInt != 0 {
+@@ -19175,12 +19175,12 @@ func rewriteBlockARM(b *Block) bool {
+ v0 := b.NewValue0(v_0.Pos, OpARMTSTconst, types.TypeFlags)
+ v0.AuxInt = c
+ v0.AddArg(x)
+- b.resetWithControl(BlockARMLE, v0)
++ b.resetWithControl(BlockARMLEnoov, v0)
+ return true
+ }
+ // match: (LE (CMPconst [0] l:(ANDshiftLL x y [c])) yes no)
+ // cond: l.Uses==1
+- // result: (LE (TSTshiftLL x y [c]) yes no)
++ // result: (LEnoov (TSTshiftLL x y [c]) yes no)
+ for b.Controls[0].Op == OpARMCMPconst {
+ v_0 := b.Controls[0]
+ if v_0.AuxInt != 0 {
+@@ -19199,12 +19199,12 @@ func rewriteBlockARM(b *Block) bool {
+ v0 := b.NewValue0(v_0.Pos, OpARMTSTshiftLL, types.TypeFlags)
+ v0.AuxInt = c
+ v0.AddArg2(x, y)
+- b.resetWithControl(BlockARMLE, v0)
++ b.resetWithControl(BlockARMLEnoov, v0)
+ return true
+ }
+ // match: (LE (CMPconst [0] l:(ANDshiftRL x y [c])) yes no)
+ // cond: l.Uses==1
+- // result: (LE (TSTshiftRL x y [c]) yes no)
++ // result: (LEnoov (TSTshiftRL x y [c]) yes no)
+ for b.Controls[0].Op == OpARMCMPconst {
+ v_0 := b.Controls[0]
+ if v_0.AuxInt != 0 {
+@@ -19223,12 +19223,12 @@ func rewriteBlockARM(b *Block) bool {
+ v0 := b.NewValue0(v_0.Pos, OpARMTSTshiftRL, types.TypeFlags)
+ v0.AuxInt = c
+ v0.AddArg2(x, y)
+- b.resetWithControl(BlockARMLE, v0)
++ b.resetWithControl(BlockARMLEnoov, v0)
+ return true
+ }
+ // match: (LE (CMPconst [0] l:(ANDshiftRA x y [c])) yes no)
+ // cond: l.Uses==1
+- // result: (LE (TSTshiftRA x y [c]) yes no)
++ // result: (LEnoov (TSTshiftRA x y [c]) yes no)
+ for b.Controls[0].Op == OpARMCMPconst {
+ v_0 := b.Controls[0]
+ if v_0.AuxInt != 0 {
+@@ -19247,12 +19247,12 @@ func rewriteBlockARM(b *Block) bool {
+ v0 := b.NewValue0(v_0.Pos, OpARMTSTshiftRA, types.TypeFlags)
+ v0.AuxInt = c
+ v0.AddArg2(x, y)
+- b.resetWithControl(BlockARMLE, v0)
++ b.resetWithControl(BlockARMLEnoov, v0)
+ return true
+ }
+ // match: (LE (CMPconst [0] l:(ANDshiftLLreg x y z)) yes no)
+ // cond: l.Uses==1
+- // result: (LE (TSTshiftLLreg x y z) yes no)
++ // result: (LEnoov (TSTshiftLLreg x y z) yes no)
+ for b.Controls[0].Op == OpARMCMPconst {
+ v_0 := b.Controls[0]
+ if v_0.AuxInt != 0 {
+@@ -19270,12 +19270,12 @@ func rewriteBlockARM(b *Block) bool {
+ }
+ v0 := b.NewValue0(v_0.Pos, OpARMTSTshiftLLreg, types.TypeFlags)
+ v0.AddArg3(x, y, z)
+- b.resetWithControl(BlockARMLE, v0)
++ b.resetWithControl(BlockARMLEnoov, v0)
+ return true
+ }
+ // match: (LE (CMPconst [0] l:(ANDshiftRLreg x y z)) yes no)
+ // cond: l.Uses==1
+- // result: (LE (TSTshiftRLreg x y z) yes no)
++ // result: (LEnoov (TSTshiftRLreg x y z) yes no)
+ for b.Controls[0].Op == OpARMCMPconst {
+ v_0 := b.Controls[0]
+ if v_0.AuxInt != 0 {
+@@ -19293,12 +19293,12 @@ func rewriteBlockARM(b *Block) bool {
+ }
+ v0 := b.NewValue0(v_0.Pos, OpARMTSTshiftRLreg, types.TypeFlags)
+ v0.AddArg3(x, y, z)
+- b.resetWithControl(BlockARMLE, v0)
++ b.resetWithControl(BlockARMLEnoov, v0)
+ return true
+ }
+ // match: (LE (CMPconst [0] l:(ANDshiftRAreg x y z)) yes no)
+ // cond: l.Uses==1
+- // result: (LE (TSTshiftRAreg x y z) yes no)
++ // result: (LEnoov (TSTshiftRAreg x y z) yes no)
+ for b.Controls[0].Op == OpARMCMPconst {
+ v_0 := b.Controls[0]
+ if v_0.AuxInt != 0 {
+@@ -19316,12 +19316,12 @@ func rewriteBlockARM(b *Block) bool {
+ }
+ v0 := b.NewValue0(v_0.Pos, OpARMTSTshiftRAreg, types.TypeFlags)
+ v0.AddArg3(x, y, z)
+- b.resetWithControl(BlockARMLE, v0)
++ b.resetWithControl(BlockARMLEnoov, v0)
+ return true
+ }
+ // match: (LE (CMPconst [0] l:(XOR x y)) yes no)
+ // cond: l.Uses==1
+- // result: (LE (TEQ x y) yes no)
++ // result: (LEnoov (TEQ x y) yes no)
+ for b.Controls[0].Op == OpARMCMPconst {
+ v_0 := b.Controls[0]
+ if v_0.AuxInt != 0 {
+@@ -19342,14 +19342,14 @@ func rewriteBlockARM(b *Block) bool {
+ }
+ v0 := b.NewValue0(v_0.Pos, OpARMTEQ, types.TypeFlags)
+ v0.AddArg2(x, y)
+- b.resetWithControl(BlockARMLE, v0)
++ b.resetWithControl(BlockARMLEnoov, v0)
+ return true
+ }
+ break
+ }
+ // match: (LE (CMPconst [0] l:(XORconst [c] x)) yes no)
+ // cond: l.Uses==1
+- // result: (LE (TEQconst [c] x) yes no)
++ // result: (LEnoov (TEQconst [c] x) yes no)
+ for b.Controls[0].Op == OpARMCMPconst {
+ v_0 := b.Controls[0]
+ if v_0.AuxInt != 0 {
+@@ -19367,12 +19367,12 @@ func rewriteBlockARM(b *Block) bool {
+ v0 := b.NewValue0(v_0.Pos, OpARMTEQconst, types.TypeFlags)
+ v0.AuxInt = c
+ v0.AddArg(x)
+- b.resetWithControl(BlockARMLE, v0)
++ b.resetWithControl(BlockARMLEnoov, v0)
+ return true
+ }
+ // match: (LE (CMPconst [0] l:(XORshiftLL x y [c])) yes no)
+ // cond: l.Uses==1
+- // result: (LE (TEQshiftLL x y [c]) yes no)
++ // result: (LEnoov (TEQshiftLL x y [c]) yes no)
+ for b.Controls[0].Op == OpARMCMPconst {
+ v_0 := b.Controls[0]
+ if v_0.AuxInt != 0 {
+@@ -19391,12 +19391,12 @@ func rewriteBlockARM(b *Block) bool {
+ v0 := b.NewValue0(v_0.Pos, OpARMTEQshiftLL, types.TypeFlags)
+ v0.AuxInt = c
+ v0.AddArg2(x, y)
+- b.resetWithControl(BlockARMLE, v0)
++ b.resetWithControl(BlockARMLEnoov, v0)
+ return true
+ }
+ // match: (LE (CMPconst [0] l:(XORshiftRL x y [c])) yes no)
+ // cond: l.Uses==1
+- // result: (LE (TEQshiftRL x y [c]) yes no)
++ // result: (LEnoov (TEQshiftRL x y [c]) yes no)
+ for b.Controls[0].Op == OpARMCMPconst {
+ v_0 := b.Controls[0]
+ if v_0.AuxInt != 0 {
+@@ -19415,12 +19415,12 @@ func rewriteBlockARM(b *Block) bool {
+ v0 := b.NewValue0(v_0.Pos, OpARMTEQshiftRL, types.TypeFlags)
+ v0.AuxInt = c
+ v0.AddArg2(x, y)
+- b.resetWithControl(BlockARMLE, v0)
++ b.resetWithControl(BlockARMLEnoov, v0)
+ return true
+ }
+ // match: (LE (CMPconst [0] l:(XORshiftRA x y [c])) yes no)
+ // cond: l.Uses==1
+- // result: (LE (TEQshiftRA x y [c]) yes no)
++ // result: (LEnoov (TEQshiftRA x y [c]) yes no)
+ for b.Controls[0].Op == OpARMCMPconst {
+ v_0 := b.Controls[0]
+ if v_0.AuxInt != 0 {
+@@ -19439,12 +19439,12 @@ func rewriteBlockARM(b *Block) bool {
+ v0 := b.NewValue0(v_0.Pos, OpARMTEQshiftRA, types.TypeFlags)
+ v0.AuxInt = c
+ v0.AddArg2(x, y)
+- b.resetWithControl(BlockARMLE, v0)
++ b.resetWithControl(BlockARMLEnoov, v0)
+ return true
+ }
+ // match: (LE (CMPconst [0] l:(XORshiftLLreg x y z)) yes no)
+ // cond: l.Uses==1
+- // result: (LE (TEQshiftLLreg x y z) yes no)
++ // result: (LEnoov (TEQshiftLLreg x y z) yes no)
+ for b.Controls[0].Op == OpARMCMPconst {
+ v_0 := b.Controls[0]
+ if v_0.AuxInt != 0 {
+@@ -19462,12 +19462,12 @@ func rewriteBlockARM(b *Block) bool {
+ }
+ v0 := b.NewValue0(v_0.Pos, OpARMTEQshiftLLreg, types.TypeFlags)
+ v0.AddArg3(x, y, z)
+- b.resetWithControl(BlockARMLE, v0)
++ b.resetWithControl(BlockARMLEnoov, v0)
+ return true
+ }
+ // match: (LE (CMPconst [0] l:(XORshiftRLreg x y z)) yes no)
+ // cond: l.Uses==1
+- // result: (LE (TEQshiftRLreg x y z) yes no)
++ // result: (LEnoov (TEQshiftRLreg x y z) yes no)
+ for b.Controls[0].Op == OpARMCMPconst {
+ v_0 := b.Controls[0]
+ if v_0.AuxInt != 0 {
+@@ -19485,12 +19485,12 @@ func rewriteBlockARM(b *Block) bool {
+ }
+ v0 := b.NewValue0(v_0.Pos, OpARMTEQshiftRLreg, types.TypeFlags)
+ v0.AddArg3(x, y, z)
+- b.resetWithControl(BlockARMLE, v0)
++ b.resetWithControl(BlockARMLEnoov, v0)
+ return true
+ }
+ // match: (LE (CMPconst [0] l:(XORshiftRAreg x y z)) yes no)
+ // cond: l.Uses==1
+- // result: (LE (TEQshiftRAreg x y z) yes no)
++ // result: (LEnoov (TEQshiftRAreg x y z) yes no)
+ for b.Controls[0].Op == OpARMCMPconst {
+ v_0 := b.Controls[0]
+ if v_0.AuxInt != 0 {
+@@ -19508,7 +19508,7 @@ func rewriteBlockARM(b *Block) bool {
+ }
+ v0 := b.NewValue0(v_0.Pos, OpARMTEQshiftRAreg, types.TypeFlags)
+ v0.AddArg3(x, y, z)
+- b.resetWithControl(BlockARMLE, v0)
++ b.resetWithControl(BlockARMLEnoov, v0)
+ return true
+ }
+ case BlockARMLEnoov:
+@@ -20009,7 +20009,7 @@ func rewriteBlockARM(b *Block) bool {
+ }
+ // match: (LT (CMPconst [0] l:(AND x y)) yes no)
+ // cond: l.Uses==1
+- // result: (LT (TST x y) yes no)
++ // result: (LTnoov (TST x y) yes no)
+ for b.Controls[0].Op == OpARMCMPconst {
+ v_0 := b.Controls[0]
+ if v_0.AuxInt != 0 {
+@@ -20030,14 +20030,14 @@ func rewriteBlockARM(b *Block) bool {
+ }
+ v0 := b.NewValue0(v_0.Pos, OpARMTST, types.TypeFlags)
+ v0.AddArg2(x, y)
+- b.resetWithControl(BlockARMLT, v0)
++ b.resetWithControl(BlockARMLTnoov, v0)
+ return true
+ }
+ break
+ }
+ // match: (LT (CMPconst [0] l:(ANDconst [c] x)) yes no)
+ // cond: l.Uses==1
+- // result: (LT (TSTconst [c] x) yes no)
++ // result: (LTnoov (TSTconst [c] x) yes no)
+ for b.Controls[0].Op == OpARMCMPconst {
+ v_0 := b.Controls[0]
+ if v_0.AuxInt != 0 {
+@@ -20055,12 +20055,12 @@ func rewriteBlockARM(b *Block) bool {
+ v0 := b.NewValue0(v_0.Pos, OpARMTSTconst, types.TypeFlags)
+ v0.AuxInt = c
+ v0.AddArg(x)
+- b.resetWithControl(BlockARMLT, v0)
++ b.resetWithControl(BlockARMLTnoov, v0)
+ return true
+ }
+ // match: (LT (CMPconst [0] l:(ANDshiftLL x y [c])) yes no)
+ // cond: l.Uses==1
+- // result: (LT (TSTshiftLL x y [c]) yes no)
++ // result: (LTnoov (TSTshiftLL x y [c]) yes no)
+ for b.Controls[0].Op == OpARMCMPconst {
+ v_0 := b.Controls[0]
+ if v_0.AuxInt != 0 {
+@@ -20079,12 +20079,12 @@ func rewriteBlockARM(b *Block) bool {
+ v0 := b.NewValue0(v_0.Pos, OpARMTSTshiftLL, types.TypeFlags)
+ v0.AuxInt = c
+ v0.AddArg2(x, y)
+- b.resetWithControl(BlockARMLT, v0)
++ b.resetWithControl(BlockARMLTnoov, v0)
+ return true
+ }
+ // match: (LT (CMPconst [0] l:(ANDshiftRL x y [c])) yes no)
+ // cond: l.Uses==1
+- // result: (LT (TSTshiftRL x y [c]) yes no)
++ // result: (LTnoov (TSTshiftRL x y [c]) yes no)
+ for b.Controls[0].Op == OpARMCMPconst {
+ v_0 := b.Controls[0]
+ if v_0.AuxInt != 0 {
+@@ -20103,12 +20103,12 @@ func rewriteBlockARM(b *Block) bool {
+ v0 := b.NewValue0(v_0.Pos, OpARMTSTshiftRL, types.TypeFlags)
+ v0.AuxInt = c
+ v0.AddArg2(x, y)
+- b.resetWithControl(BlockARMLT, v0)
++ b.resetWithControl(BlockARMLTnoov, v0)
+ return true
+ }
+ // match: (LT (CMPconst [0] l:(ANDshiftRA x y [c])) yes no)
+ // cond: l.Uses==1
+- // result: (LT (TSTshiftRA x y [c]) yes no)
++ // result: (LTnoov (TSTshiftRA x y [c]) yes no)
+ for b.Controls[0].Op == OpARMCMPconst {
+ v_0 := b.Controls[0]
+ if v_0.AuxInt != 0 {
+@@ -20127,12 +20127,12 @@ func rewriteBlockARM(b *Block) bool {
+ v0 := b.NewValue0(v_0.Pos, OpARMTSTshiftRA, types.TypeFlags)
+ v0.AuxInt = c
+ v0.AddArg2(x, y)
+- b.resetWithControl(BlockARMLT, v0)
++ b.resetWithControl(BlockARMLTnoov, v0)
+ return true
+ }
+ // match: (LT (CMPconst [0] l:(ANDshiftLLreg x y z)) yes no)
+ // cond: l.Uses==1
+- // result: (LT (TSTshiftLLreg x y z) yes no)
++ // result: (LTnoov (TSTshiftLLreg x y z) yes no)
+ for b.Controls[0].Op == OpARMCMPconst {
+ v_0 := b.Controls[0]
+ if v_0.AuxInt != 0 {
+@@ -20150,12 +20150,12 @@ func rewriteBlockARM(b *Block) bool {
+ }
+ v0 := b.NewValue0(v_0.Pos, OpARMTSTshiftLLreg, types.TypeFlags)
+ v0.AddArg3(x, y, z)
+- b.resetWithControl(BlockARMLT, v0)
++ b.resetWithControl(BlockARMLTnoov, v0)
+ return true
+ }
+ // match: (LT (CMPconst [0] l:(ANDshiftRLreg x y z)) yes no)
+ // cond: l.Uses==1
+- // result: (LT (TSTshiftRLreg x y z) yes no)
++ // result: (LTnoov (TSTshiftRLreg x y z) yes no)
+ for b.Controls[0].Op == OpARMCMPconst {
+ v_0 := b.Controls[0]
+ if v_0.AuxInt != 0 {
+@@ -20173,12 +20173,12 @@ func rewriteBlockARM(b *Block) bool {
+ }
+ v0 := b.NewValue0(v_0.Pos, OpARMTSTshiftRLreg, types.TypeFlags)
+ v0.AddArg3(x, y, z)
+- b.resetWithControl(BlockARMLT, v0)
++ b.resetWithControl(BlockARMLTnoov, v0)
+ return true
+ }
+ // match: (LT (CMPconst [0] l:(ANDshiftRAreg x y z)) yes no)
+ // cond: l.Uses==1
+- // result: (LT (TSTshiftRAreg x y z) yes no)
++ // result: (LTnoov (TSTshiftRAreg x y z) yes no)
+ for b.Controls[0].Op == OpARMCMPconst {
+ v_0 := b.Controls[0]
+ if v_0.AuxInt != 0 {
+@@ -20196,12 +20196,12 @@ func rewriteBlockARM(b *Block) bool {
+ }
+ v0 := b.NewValue0(v_0.Pos, OpARMTSTshiftRAreg, types.TypeFlags)
+ v0.AddArg3(x, y, z)
+- b.resetWithControl(BlockARMLT, v0)
++ b.resetWithControl(BlockARMLTnoov, v0)
+ return true
+ }
+ // match: (LT (CMPconst [0] l:(XOR x y)) yes no)
+ // cond: l.Uses==1
+- // result: (LT (TEQ x y) yes no)
++ // result: (LTnoov (TEQ x y) yes no)
+ for b.Controls[0].Op == OpARMCMPconst {
+ v_0 := b.Controls[0]
+ if v_0.AuxInt != 0 {
+@@ -20222,14 +20222,14 @@ func rewriteBlockARM(b *Block) bool {
+ }
+ v0 := b.NewValue0(v_0.Pos, OpARMTEQ, types.TypeFlags)
+ v0.AddArg2(x, y)
+- b.resetWithControl(BlockARMLT, v0)
++ b.resetWithControl(BlockARMLTnoov, v0)
+ return true
+ }
+ break
+ }
+ // match: (LT (CMPconst [0] l:(XORconst [c] x)) yes no)
+ // cond: l.Uses==1
+- // result: (LT (TEQconst [c] x) yes no)
++ // result: (LTnoov (TEQconst [c] x) yes no)
+ for b.Controls[0].Op == OpARMCMPconst {
+ v_0 := b.Controls[0]
+ if v_0.AuxInt != 0 {
+@@ -20247,12 +20247,12 @@ func rewriteBlockARM(b *Block) bool {
+ v0 := b.NewValue0(v_0.Pos, OpARMTEQconst, types.TypeFlags)
+ v0.AuxInt = c
+ v0.AddArg(x)
+- b.resetWithControl(BlockARMLT, v0)
++ b.resetWithControl(BlockARMLTnoov, v0)
+ return true
+ }
+ // match: (LT (CMPconst [0] l:(XORshiftLL x y [c])) yes no)
+ // cond: l.Uses==1
+- // result: (LT (TEQshiftLL x y [c]) yes no)
++ // result: (LTnoov (TEQshiftLL x y [c]) yes no)
+ for b.Controls[0].Op == OpARMCMPconst {
+ v_0 := b.Controls[0]
+ if v_0.AuxInt != 0 {
+@@ -20271,12 +20271,12 @@ func rewriteBlockARM(b *Block) bool {
+ v0 := b.NewValue0(v_0.Pos, OpARMTEQshiftLL, types.TypeFlags)
+ v0.AuxInt = c
+ v0.AddArg2(x, y)
+- b.resetWithControl(BlockARMLT, v0)
++ b.resetWithControl(BlockARMLTnoov, v0)
+ return true
+ }
+ // match: (LT (CMPconst [0] l:(XORshiftRL x y [c])) yes no)
+ // cond: l.Uses==1
+- // result: (LT (TEQshiftRL x y [c]) yes no)
++ // result: (LTnoov (TEQshiftRL x y [c]) yes no)
+ for b.Controls[0].Op == OpARMCMPconst {
+ v_0 := b.Controls[0]
+ if v_0.AuxInt != 0 {
+@@ -20295,12 +20295,12 @@ func rewriteBlockARM(b *Block) bool {
+ v0 := b.NewValue0(v_0.Pos, OpARMTEQshiftRL, types.TypeFlags)
+ v0.AuxInt = c
+ v0.AddArg2(x, y)
+- b.resetWithControl(BlockARMLT, v0)
++ b.resetWithControl(BlockARMLTnoov, v0)
+ return true
+ }
+ // match: (LT (CMPconst [0] l:(XORshiftRA x y [c])) yes no)
+ // cond: l.Uses==1
+- // result: (LT (TEQshiftRA x y [c]) yes no)
++ // result: (LTnoov (TEQshiftRA x y [c]) yes no)
+ for b.Controls[0].Op == OpARMCMPconst {
+ v_0 := b.Controls[0]
+ if v_0.AuxInt != 0 {
+@@ -20319,12 +20319,12 @@ func rewriteBlockARM(b *Block) bool {
+ v0 := b.NewValue0(v_0.Pos, OpARMTEQshiftRA, types.TypeFlags)
+ v0.AuxInt = c
+ v0.AddArg2(x, y)
+- b.resetWithControl(BlockARMLT, v0)
++ b.resetWithControl(BlockARMLTnoov, v0)
+ return true
+ }
+ // match: (LT (CMPconst [0] l:(XORshiftLLreg x y z)) yes no)
+ // cond: l.Uses==1
+- // result: (LT (TEQshiftLLreg x y z) yes no)
++ // result: (LTnoov (TEQshiftLLreg x y z) yes no)
+ for b.Controls[0].Op == OpARMCMPconst {
+ v_0 := b.Controls[0]
+ if v_0.AuxInt != 0 {
+@@ -20342,12 +20342,12 @@ func rewriteBlockARM(b *Block) bool {
+ }
+ v0 := b.NewValue0(v_0.Pos, OpARMTEQshiftLLreg, types.TypeFlags)
+ v0.AddArg3(x, y, z)
+- b.resetWithControl(BlockARMLT, v0)
++ b.resetWithControl(BlockARMLTnoov, v0)
+ return true
+ }
+ // match: (LT (CMPconst [0] l:(XORshiftRLreg x y z)) yes no)
+ // cond: l.Uses==1
+- // result: (LT (TEQshiftRLreg x y z) yes no)
++ // result: (LTnoov (TEQshiftRLreg x y z) yes no)
+ for b.Controls[0].Op == OpARMCMPconst {
+ v_0 := b.Controls[0]
+ if v_0.AuxInt != 0 {
+@@ -20365,12 +20365,12 @@ func rewriteBlockARM(b *Block) bool {
+ }
+ v0 := b.NewValue0(v_0.Pos, OpARMTEQshiftRLreg, types.TypeFlags)
+ v0.AddArg3(x, y, z)
+- b.resetWithControl(BlockARMLT, v0)
++ b.resetWithControl(BlockARMLTnoov, v0)
+ return true
+ }
+ // match: (LT (CMPconst [0] l:(XORshiftRAreg x y z)) yes no)
+ // cond: l.Uses==1
+- // result: (LT (TEQshiftRAreg x y z) yes no)
++ // result: (LTnoov (TEQshiftRAreg x y z) yes no)
+ for b.Controls[0].Op == OpARMCMPconst {
+ v_0 := b.Controls[0]
+ if v_0.AuxInt != 0 {
+@@ -20388,7 +20388,7 @@ func rewriteBlockARM(b *Block) bool {
+ }
+ v0 := b.NewValue0(v_0.Pos, OpARMTEQshiftRAreg, types.TypeFlags)
+ v0.AddArg3(x, y, z)
+- b.resetWithControl(BlockARMLT, v0)
++ b.resetWithControl(BlockARMLTnoov, v0)
+ return true
+ }
+ case BlockARMLTnoov:
+diff --git a/test/fixedbugs/issue42876.go b/test/fixedbugs/issue42876.go
+new file mode 100644
+index 0000000000..67cf4919ac
+--- /dev/null
++++ b/test/fixedbugs/issue42876.go
+@@ -0,0 +1,18 @@
++// run
++
++// Copyright 2020 The Go Authors. All rights reserved.
++// Use of this source code is governed by a BSD-style
++// license that can be found in the LICENSE file.
++
++package main
++
++var x = [4]int32{-0x7fffffff, 0x7fffffff, 2, 4}
++
++func main() {
++ if x[0] > x[1] {
++ panic("fail 1")
++ }
++ if x[2]&x[3] < 0 {
++ panic("fail 2") // Fails here
++ }
++}
+--
+2.27.0
+
diff --git a/0016-release-branch.go1.15-syscall-do-not-overflow-key-me.patch b/0016-release-branch.go1.15-syscall-do-not-overflow-key-me.patch
new file mode 100644
index 0000000..08f29f3
--- /dev/null
+++ b/0016-release-branch.go1.15-syscall-do-not-overflow-key-me.patch
@@ -0,0 +1,115 @@
+From 4fda89d4201fc9f0c1e192bbcc95dd8d660e9122 Mon Sep 17 00:00:00 2001
+From: "Jason A. Donenfeld"
+Date: Tue, 23 Feb 2021 13:29:40 +0100
+Subject: [PATCH 16/44] [release-branch.go1.15] syscall: do not overflow key
+ memory in GetQueuedCompletionStatus
+
+The third argument to GetQueuedCompletionStatus is a pointer to a
+uintptr, not a uint32. Users of this functions have therefore been
+corrupting their memory every time they used it. Either that memory
+corruption was silent (dangerous), or their programs didn't work so they
+chose a different API to use.
+
+This fixes the problem by passing through an intermediate buffer.
+
+Updates #44538.
+Fixes #44592.
+
+Change-Id: Icacd71f705b36e41e52bd8c4d74898559a27522f
+Reviewed-on: https://go-review.googlesource.com/c/go/+/296151
+Trust: Jason A. Donenfeld
+Run-TryBot: Jason A. Donenfeld
+TryBot-Result: Go Bot
+Reviewed-by: Bryan C. Mills
+
+Conflict:NA
+Reference:https://github.com/golang/go/commit/4fda89d4201fc9f0c1e192bbcc95dd8d660e9122
+
+---
+ src/syscall/syscall_windows.go | 34 ++++++++++++++++++++++++++++++---
+ src/syscall/zsyscall_windows.go | 6 +++---
+ 2 files changed, 34 insertions(+), 6 deletions(-)
+
+diff --git a/src/syscall/syscall_windows.go b/src/syscall/syscall_windows.go
+index f62c00d72f..fbb11a89ca 100644
+--- a/src/syscall/syscall_windows.go
++++ b/src/syscall/syscall_windows.go
+@@ -213,9 +213,9 @@ func NewCallbackCDecl(fn interface{}) uintptr {
+ //sys SetEndOfFile(handle Handle) (err error)
+ //sys GetSystemTimeAsFileTime(time *Filetime)
+ //sys GetTimeZoneInformation(tzi *Timezoneinformation) (rc uint32, err error) [failretval==0xffffffff]
+-//sys CreateIoCompletionPort(filehandle Handle, cphandle Handle, key uint32, threadcnt uint32) (handle Handle, err error)
+-//sys GetQueuedCompletionStatus(cphandle Handle, qty *uint32, key *uint32, overlapped **Overlapped, timeout uint32) (err error)
+-//sys PostQueuedCompletionStatus(cphandle Handle, qty uint32, key uint32, overlapped *Overlapped) (err error)
++//sys createIoCompletionPort(filehandle Handle, cphandle Handle, key uintptr, threadcnt uint32) (handle Handle, err error) = CreateIoCompletionPort
++//sys getQueuedCompletionStatus(cphandle Handle, qty *uint32, key *uintptr, overlapped **Overlapped, timeout uint32) (err error) = GetQueuedCompletionStatus
++//sys postQueuedCompletionStatus(cphandle Handle, qty uint32, key uintptr, overlapped *Overlapped) (err error) = PostQueuedCompletionStatus
+ //sys CancelIo(s Handle) (err error)
+ //sys CancelIoEx(s Handle, o *Overlapped) (err error)
+ //sys CreateProcess(appName *uint16, commandLine *uint16, procSecurity *SecurityAttributes, threadSecurity *SecurityAttributes, inheritHandles bool, creationFlags uint32, env *uint16, currentDir *uint16, startupInfo *StartupInfo, outProcInfo *ProcessInformation) (err error) = CreateProcessW
+@@ -1209,3 +1209,31 @@ func Readlink(path string, buf []byte) (n int, err error) {
+
+ return n, nil
+ }
++
++// Deprecated: CreateIoCompletionPort has the wrong function signature. Use x/sys/windows.CreateIoCompletionPort.
++func CreateIoCompletionPort(filehandle Handle, cphandle Handle, key uint32, threadcnt uint32) (Handle, error) {
++ return createIoCompletionPort(filehandle, cphandle, uintptr(key), threadcnt)
++}
++
++// Deprecated: GetQueuedCompletionStatus has the wrong function signature. Use x/sys/windows.GetQueuedCompletionStatus.
++func GetQueuedCompletionStatus(cphandle Handle, qty *uint32, key *uint32, overlapped **Overlapped, timeout uint32) error {
++ var ukey uintptr
++ var pukey *uintptr
++ if key != nil {
++ ukey = uintptr(*key)
++ pukey = &ukey
++ }
++ err := getQueuedCompletionStatus(cphandle, qty, pukey, overlapped, timeout)
++ if key != nil {
++ *key = uint32(ukey)
++ if uintptr(*key) != ukey && err == nil {
++ err = errorspkg.New("GetQueuedCompletionStatus returned key overflow")
++ }
++ }
++ return err
++}
++
++// Deprecated: PostQueuedCompletionStatus has the wrong function signature. Use x/sys/windows.PostQueuedCompletionStatus.
++func PostQueuedCompletionStatus(cphandle Handle, qty uint32, key uint32, overlapped *Overlapped) error {
++ return postQueuedCompletionStatus(cphandle, qty, uintptr(key), overlapped)
++}
+diff --git a/src/syscall/zsyscall_windows.go b/src/syscall/zsyscall_windows.go
+index 2348f6534f..2762fb3b74 100644
+--- a/src/syscall/zsyscall_windows.go
++++ b/src/syscall/zsyscall_windows.go
+@@ -539,7 +539,7 @@ func GetTimeZoneInformation(tzi *Timezoneinformation) (rc uint32, err error) {
+ return
+ }
+
+-func CreateIoCompletionPort(filehandle Handle, cphandle Handle, key uint32, threadcnt uint32) (handle Handle, err error) {
++func createIoCompletionPort(filehandle Handle, cphandle Handle, key uintptr, threadcnt uint32) (handle Handle, err error) {
+ r0, _, e1 := Syscall6(procCreateIoCompletionPort.Addr(), 4, uintptr(filehandle), uintptr(cphandle), uintptr(key), uintptr(threadcnt), 0, 0)
+ handle = Handle(r0)
+ if handle == 0 {
+@@ -552,7 +552,7 @@ func CreateIoCompletionPort(filehandle Handle, cphandle Handle, key uint32, thre
+ return
+ }
+
+-func GetQueuedCompletionStatus(cphandle Handle, qty *uint32, key *uint32, overlapped **Overlapped, timeout uint32) (err error) {
++func getQueuedCompletionStatus(cphandle Handle, qty *uint32, key *uintptr, overlapped **Overlapped, timeout uint32) (err error) {
+ r1, _, e1 := Syscall6(procGetQueuedCompletionStatus.Addr(), 5, uintptr(cphandle), uintptr(unsafe.Pointer(qty)), uintptr(unsafe.Pointer(key)), uintptr(unsafe.Pointer(overlapped)), uintptr(timeout), 0)
+ if r1 == 0 {
+ if e1 != 0 {
+@@ -564,7 +564,7 @@ func GetQueuedCompletionStatus(cphandle Handle, qty *uint32, key *uint32, overla
+ return
+ }
+
+-func PostQueuedCompletionStatus(cphandle Handle, qty uint32, key uint32, overlapped *Overlapped) (err error) {
++func postQueuedCompletionStatus(cphandle Handle, qty uint32, key uintptr, overlapped *Overlapped) (err error) {
+ r1, _, e1 := Syscall6(procPostQueuedCompletionStatus.Addr(), 4, uintptr(cphandle), uintptr(qty), uintptr(key), uintptr(unsafe.Pointer(overlapped)), 0, 0)
+ if r1 == 0 {
+ if e1 != 0 {
+--
+2.27.0
+
diff --git a/0017-release-branch.go1.15-time-correct-unusual-extension.patch b/0017-release-branch.go1.15-time-correct-unusual-extension.patch
new file mode 100644
index 0000000..9c58dc7
--- /dev/null
+++ b/0017-release-branch.go1.15-time-correct-unusual-extension.patch
@@ -0,0 +1,150 @@
+From 6bb96000b3215a84d0a5193e387cf809d2fa2800 Mon Sep 17 00:00:00 2001
+From: Ian Lance Taylor
+Date: Thu, 25 Feb 2021 10:01:56 -0800
+Subject: [PATCH 17/44] [release-branch.go1.15] time: correct unusual extension
+ string cases
+
+This fixes two uncommon cases.
+
+First, the tzdata code permits timezone offsets up to 24 * 7, although
+the POSIX TZ parsing does not. The tzdata code uses this to specify a
+day of week in some cases.
+
+Second, we incorrectly rejected a negative time offset for when a time
+zone change comes into effect.
+
+For #44385
+Fixes #44617
+
+Change-Id: I5f2efc1d385e9bfa974a0de3fa81e7a94b827602
+Reviewed-on: https://go-review.googlesource.com/c/go/+/296392
+Trust: Ian Lance Taylor
+Run-TryBot: Ian Lance Taylor
+TryBot-Result: Go Bot
+Reviewed-by: Tobias Klauser
+(cherry picked from commit d9fd38e68ba00a51c2c7363150688d0e7687ef84)
+Reviewed-on: https://go-review.googlesource.com/c/go/+/297229
+
+Conflict:NA
+Reference:https://github.com/golang/go/commit/6bb96000b3215a84d0a5193e387cf809d2fa2800
+
+---
+ src/time/zoneinfo.go | 6 ++--
+ src/time/zoneinfo_test.go | 60 +++++++++++++++++++++++++++++----------
+ 2 files changed, 49 insertions(+), 17 deletions(-)
+
+diff --git a/src/time/zoneinfo.go b/src/time/zoneinfo.go
+index c3662297c7..6db9443474 100644
+--- a/src/time/zoneinfo.go
++++ b/src/time/zoneinfo.go
+@@ -377,8 +377,10 @@ func tzsetOffset(s string) (offset int, rest string, ok bool) {
+ neg = true
+ }
+
++ // The tzdata code permits values up to 24 * 7 here,
++ // although POSIX does not.
+ var hours int
+- hours, s, ok = tzsetNum(s, 0, 24)
++ hours, s, ok = tzsetNum(s, 0, 24*7)
+ if !ok {
+ return 0, "", false
+ }
+@@ -487,7 +489,7 @@ func tzsetRule(s string) (rule, string, bool) {
+ }
+
+ offset, s, ok := tzsetOffset(s[1:])
+- if !ok || offset < 0 {
++ if !ok {
+ return rule{}, "", false
+ }
+ r.time = offset
+diff --git a/src/time/zoneinfo_test.go b/src/time/zoneinfo_test.go
+index 277b68f798..d043e1e9f1 100644
+--- a/src/time/zoneinfo_test.go
++++ b/src/time/zoneinfo_test.go
+@@ -183,22 +183,50 @@ func TestMalformedTZData(t *testing.T) {
+ }
+ }
+
+-func TestLoadLocationFromTZDataSlim(t *testing.T) {
+- // A 2020b slim tzdata for Europe/Berlin
+- tzData := "TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00<\x00\x00\x00\x04\x00\x00\x00\x12\xff\xff\xff\xffo\xa2a\xf8\xff\xff\xff\xff\x9b\f\x17`\xff\xff\xff\xff\x9b\xd5\xda\xf0\xff\xff\xff\xff\x9cٮ\x90\xff\xff\xff\xff\x9d\xa4\xb5\x90\xff\xff\xff\xff\x9e\xb9\x90\x90\xff\xff\xff\xff\x9f\x84\x97\x90\xff\xff\xff\xff\xc8\tq\x90\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xffϒ4\x10\xff\xff\xff\xffЂ%\x10\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xffѶ\x96\x00\xff\xff\xff\xff\xd2X\xbe\x80\xff\xff\xff\xffҡO\x10\xff\xff\xff\xff\xd3c\x1b\x90\xff\xff\xff\xff\xd4K#\x90\xff\xff\xff\xff\xd59\xd1 \xff\xff\xff\xff\xd5g\xe7\x90\xff\xff\xff\xffըs\x00\xff\xff\xff\xff\xd6)\xb4\x10\xff\xff\xff\xff\xd7,\x1a\x10\xff\xff\xff\xff\xd8\t\x96\x10\xff\xff\xff\xff\xd9\x02\xc1\x90\xff\xff\xff\xff\xd9\xe9x\x10\x00\x00\x00\x00\x13MD\x10\x00\x00\x00\x00\x143\xfa\x90\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13ܐ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#3<-02>,M3.5.0/-2,M10.5.0/-1\n",
++ wantName: "-03",
++ wantOffset: -10800,
++ },
++ {
++ // 2021a slim tzdata for Asia/Gaza.
++ zoneName: "Asia/Gaza",
++ tzData: "TZif3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00s\x00\x00\x00\x05\x00\x00\x00\x15\xff\xff\xff\xff}\xbdJ\xb0\xff\xff\xff\xff\xc8Y\xcf\x00\xff\xff\xff\xff\xc8\xfa\xa6\x00\xff\xff\xff\xff\xc98\x9c\x80\xff\xff\xff\xff\xcc\xe5\xeb\x80\xff\xff\xff\xffͬ\xfe\x00\xff\xff\xff\xff\xce\xc7\x1f\x00\xff\xff\xff\xffϏ\x83\x00\xff\xff\xff\xffЩ\xa4\x00\xff\xff\xff\xffф}\x00\xff\xff\xff\xffҊ׀\xff\xff\xff\xff\xd3e\xb0\x80\xff\xff\xff\xff\xd4l\v\x00\xff\xff\xff\xff\xe86c`\xff\xff\xff\xff\xe8\xf4-P\xff\xff\xff\xff\xea\v\xb9`\xff\xff\xff\xff\xea\xd5`\xd0\xff\xff\xff\xff\xeb\xec\xfa\xf0\xff\xff\xff\xff\xec\xb5m\x00\xff\xff\xff\xff\xed\xcf\u007f\xf0\xff\xff\xff\xff\xee\x97\xf2\x00\xff\xff\xff\xffﰳp\xff\xff\xff\xff\xf0y%\x80\xff\xff\xff\xff\xf1\x91\xe6\xf0\xff\xff\xff\xff\xf2ZY\x00\xff\xff\xff\xff\xf3s\x1ap\xff\xff\xff\xff\xf4;\x8c\x80\xff\xff\xff\xff\xf5U\x9fp\xff\xff\xff\xff\xf6\x1e\x11\x80\xff\xff\xff\xff\xf76\xd2\xf0\xff\xff\xff\xff\xf7\xffE\x00\xff\xff\xff\xff\xf9\x18\x06p\xff\xff\xff\xff\xf9\xe1\xca\x00\xff\xff\xff\xff\xfa\xf99\xf0\xff\xff\xff\xff\xfb'BP\x00\x00\x00\x00\b|\x8b\xe0\x00\x00\x00\x00\b\xfd\xb0\xd0\x00\x00\x00\x00\t\xf6\xea`\x00\x00\x00\x00\n\xa63\xd0\x00\x00\x00\x00\x13\xe9\xfc`\x00\x00\x00\x00\x14![`\x00\x00\x00\x00\x1a\xfa\xc6`\x00\x00\x00\x00\x1b\x8en`\x00\x00\x00\x00\x1c\xbe\xf8\xe0\x00\x00\x00\x00\x1dw|\xd0\x00\x00\x00\x00\x1e\xcc\xff`\x00\x00\x00\x00\x1f`\x99P\x00\x00\x00\x00 \x82\xb1`\x00\x00\x00\x00!I\xb5\xd0\x00\x00\x00\x00\"^\x9e\xe0\x00\x00\x00\x00# ]P\x00\x00\x00\x00$Z0`\x00\x00\x00\x00%\x00?P\x00\x00\x00\x00&\v\xed\xe0\x00\x00\x00\x00&\xd6\xe6\xd0\x00\x00\x00\x00'\xeb\xcf\xe0\x00\x00\x00\x00(\xc0\x03P\x00\x00\x00\x00)\xd4\xec`\x00\x00\x00\x00*\xa9\x1f\xd0\x00\x00\x00\x00+\xbbe\xe0\x00\x00\x00\x00,\x89\x01\xd0\x00\x00\x00\x00-\x9bG\xe0\x00\x00\x00\x00._\xa9P\x00\x00\x00\x00/{)\xe0\x00\x00\x00\x000H\xc5\xd0\x00\x00\x00\x000\xe7\a\xe0\x00\x00\x00\x001dF`\x00\x00\x00\x002A\xc2`\x00\x00\x00\x003D(`\x00\x00\x00\x004!\xa4`\x00\x00\x00\x005$\n`\x00\x00\x00\x006\x01\x86`\x00\x00\x00\x007\x16a`\x00\x00\x00\x008\x06DP\x00\x00\x00\x008\xff}\xe0\x00\x00\x00\x009\xef`\xd0\x00\x00\x00\x00:\xdf_\xe0\x00\x00\x00\x00;\xcfB\xd0\x00\x00\x00\x00<\xbfA\xe0\x00\x00\x00\x00=\xaf$\xd0\x00\x00\x00\x00>\x9f#\xe0\x00\x00\x00\x00?\x8f\x06\xd0\x00\x00\x00\x00@\u007f\x05\xe0\x00\x00\x00\x00A\\\x81\xe0\x00\x00\x00\x00B^\xe7\xe0\x00\x00\x00\x00CA\xb7\xf0\x00\x00\x00\x00D-\xa6`\x00\x00\x00\x00E\x12\xfdP\x00\x00\x00\x00F\x0e\xd9\xe0\x00\x00\x00\x00F\xe8op\x00\x00\x00\x00G\xec\x18\xe0\x00\x00\x00\x00H\xb7\x11\xd0\x00\x00\x00\x00I\xcb\xfa\xe0\x00\x00\x00\x00J\xa0<`\x00\x00\x00\x00K\xad.\x9c\x00\x00\x00\x00La\xbd\xd0\x00\x00\x00\x00M\x94\xf9\x9c\x00\x00\x00\x00N5\xc2P\x00\x00\x00\x00Ot\xdb`\x00\x00\x00\x00P[\x91\xe0\x00\x00\x00\x00QT\xbd`\x00\x00\x00\x00RD\xa0P\x00\x00\x00\x00S4\x9f`\x00\x00\x00\x00TIlP\x00\x00\x00\x00U\x15\xd2\xe0\x00\x00\x00\x00V)\\`\x00\x00\x00\x00V\xf5\xc2\xf0\x00\x00\x00\x00X\x13\xca`\x00\x00\x00\x00Xդ\xf0\x00\x00\x00\x00Y\xf3\xac`\x00\x00\x00\x00Z\xb5\x86\xf0\x00\x00\x00\x00[ӎ`\x00\x00\x00\x00\\\x9dC\xe0\x00\x00\x00\x00]\xb3bP\x00\x00\x00\x00^~w`\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x00\x00 P\x00\x00\x00\x00*0\x01\x04\x00\x00\x1c \x00\t\x00\x00*0\x01\r\x00\x00\x1c \x00\x11LMT\x00EEST\x00EET\x00IDT\x00IST\x00\nEET-2EEST,M3.4.4/48,M10.4.4/49\n",
++ wantName: "EET",
++ wantOffset: 7200,
++ },
++}
+
+- reference, err := time.LoadLocationFromTZData("Europe/Berlin", []byte(tzData))
+- if err != nil {
+- t.Fatal(err)
+- }
++func TestLoadLocationFromTZDataSlim(t *testing.T) {
++ for _, test := range slimTests {
++ reference, err := time.LoadLocationFromTZData(test.zoneName, []byte(test.tzData))
++ if err != nil {
++ t.Fatal(err)
++ }
+
+- d := time.Date(2020, time.October, 29, 15, 30, 0, 0, reference)
+- tzName, tzOffset := d.Zone()
+- if want := "CET"; tzName != want {
+- t.Errorf("Zone name == %s, want %s", tzName, want)
+- }
+- if want := 3600; tzOffset != want {
+- t.Errorf("Zone offset == %d, want %d", tzOffset, want)
++ d := time.Date(2020, time.October, 29, 15, 30, 0, 0, reference)
++ tzName, tzOffset := d.Zone()
++ if tzName != test.wantName {
++ t.Errorf("Zone name == %s, want %s", tzName, test.wantName)
++ }
++ if tzOffset != test.wantOffset {
++ t.Errorf("Zone offset == %d, want %d", tzOffset, test.wantOffset)
++ }
+ }
+ }
+
+@@ -263,7 +291,8 @@ func TestTzsetOffset(t *testing.T) {
+ {"+08", 8 * 60 * 60, "", true},
+ {"-01:02:03", -1*60*60 - 2*60 - 3, "", true},
+ {"01", 1 * 60 * 60, "", true},
+- {"100", 0, "", false},
++ {"100", 100 * 60 * 60, "", true},
++ {"1000", 0, "", false},
+ {"8PDT", 8 * 60 * 60, "PDT", true},
+ } {
+ off, out, ok := time.TzsetOffset(test.in)
+@@ -288,6 +317,7 @@ func TestTzsetRule(t *testing.T) {
+ {"30/03:00:00", time.Rule{Kind: time.RuleDOY, Day: 30, Time: 3 * 60 * 60}, "", true},
+ {"M4.5.6/03:00:00", time.Rule{Kind: time.RuleMonthWeekDay, Mon: 4, Week: 5, Day: 6, Time: 3 * 60 * 60}, "", true},
+ {"M4.5.7/03:00:00", time.Rule{}, "", false},
++ {"M4.5.6/-04", time.Rule{Kind: time.RuleMonthWeekDay, Mon: 4, Week: 5, Day: 6, Time: -4 * 60 * 60}, "", true},
+ } {
+ r, out, ok := time.TzsetRule(test.in)
+ if r != test.r || out != test.out || ok != test.ok {
+--
+2.27.0
+
diff --git a/0018-release-branch.go1.15-cmd-compile-fix-escape-analysi.patch b/0018-release-branch.go1.15-cmd-compile-fix-escape-analysi.patch
new file mode 100644
index 0000000..e13076f
--- /dev/null
+++ b/0018-release-branch.go1.15-cmd-compile-fix-escape-analysi.patch
@@ -0,0 +1,87 @@
+From f75ab2d5a61f1a5aabaffe7752110e2dcd581236 Mon Sep 17 00:00:00 2001
+From: Matthew Dempsky
+Date: Sat, 27 Feb 2021 09:41:19 -0800
+Subject: [PATCH 18/44] [release-branch.go1.15] cmd/compile: fix escape
+ analysis of heap-allocated results
+
+One of escape analysis's responsibilities is to summarize whether/how
+each function parameter flows to the heap so we can correctly
+incorporate those flows into callers' escape analysis data flow
+graphs.
+
+As an optimization, we separately record when parameters flow to
+result parameters, so that we can more precisely analyze parameter
+flows based on how the results are used at the call site. However, if
+a named result parameter itself needs to be heap allocated, this
+optimization isn't safe and the parameter needs to be recorded as
+flowing to heap rather than flowing to result.
+
+Escape analysis used to get this correct because it conservatively
+rewalked the data-flow graph multiple times. So even though it would
+incorrectly record the result parameter flow, it would separately find
+a flow to the heap. However, CL 196811 (specifically, case 3)
+optimized the walking logic to reduce unnecessary rewalks causing us
+to stop finding the extra heap flow.
+
+This CL fixes the issue by correcting location.leakTo to be sensitive
+to sink.escapes and not record result-flows when the result parameter
+escapes to the heap.
+
+Fixes #44658.
+
+Change-Id: I48742ed35a6cab591094e2d23a439e205bd65c50
+Reviewed-on: https://go-review.googlesource.com/c/go/+/297289
+Trust: Matthew Dempsky
+Run-TryBot: Matthew Dempsky
+TryBot-Result: Go Bot
+Reviewed-by: Keith Randall
+Reviewed-on: https://go-review.googlesource.com/c/go/+/297291
+
+Conflict:NA
+Reference:https://github.com/golang/go/commit/f75ab2d5a61f1a5aabaffe7752110e2dcd581236
+
+---
+ src/cmd/compile/internal/gc/escape.go | 7 ++++---
+ test/escape5.go | 11 +++++++++++
+ 2 files changed, 15 insertions(+), 3 deletions(-)
+
+diff --git a/src/cmd/compile/internal/gc/escape.go b/src/cmd/compile/internal/gc/escape.go
+index 08000dd374..2c55163100 100644
+--- a/src/cmd/compile/internal/gc/escape.go
++++ b/src/cmd/compile/internal/gc/escape.go
+@@ -1379,9 +1379,10 @@ func containsClosure(f, c *Node) bool {
+
+ // leak records that parameter l leaks to sink.
+ func (l *EscLocation) leakTo(sink *EscLocation, derefs int) {
+- // If sink is a result parameter and we can fit return bits
+- // into the escape analysis tag, then record a return leak.
+- if sink.isName(PPARAMOUT) && sink.curfn == l.curfn {
++ // If sink is a result parameter that doesn't escape (#44614)
++ // and we can fit return bits into the escape analysis tag,
++ // then record as a result leak.
++ if !sink.escapes && sink.isName(PPARAMOUT) && sink.curfn == l.curfn {
+ // TODO(mdempsky): Eliminate dependency on Vargen here.
+ ri := int(sink.n.Name.Vargen) - 1
+ if ri < numEscResults {
+diff --git a/test/escape5.go b/test/escape5.go
+index 061e57a069..145c5dd900 100644
+--- a/test/escape5.go
++++ b/test/escape5.go
+@@ -262,3 +262,14 @@ func f28369(n int) int {
+
+ return 1 + f28369(n-1)
+ }
++
++// Issue 44614: parameters that flow to a heap-allocated result
++// parameter must be recorded as a heap-flow rather than a
++// result-flow.
++
++// N.B., must match "leaking param: p",
++// but *not* "leaking param: p to result r level=0".
++func f(p *int) (r *int) { // ERROR "leaking param: p$" "moved to heap: r"
++ sink4 = &r
++ return p
++}
+--
+2.27.0
+
diff --git a/0019-release-branch.go1.15-net-http-ignore-connection-clo.patch b/0019-release-branch.go1.15-net-http-ignore-connection-clo.patch
new file mode 100644
index 0000000..38b1bc7
--- /dev/null
+++ b/0019-release-branch.go1.15-net-http-ignore-connection-clo.patch
@@ -0,0 +1,124 @@
+From 5de8d3bfcb060bbc61b9b9c945055fd3fb5b9607 Mon Sep 17 00:00:00 2001
+From: Michael Fraenkel
+Date: Sat, 26 Sep 2020 09:20:16 -0600
+Subject: [PATCH 19/44] [release-branch.go1.15] net/http: ignore connection
+ closes once done with the connection
+
+Once the connection is put back into the idle pool, the request should
+not take any action if the connection is closed.
+
+For #42935.
+Updates #41600.
+
+Change-Id: I5e4ddcdc03cd44f5197ecfbe324638604961de84
+Reviewed-on: https://go-review.googlesource.com/c/go/+/257818
+Reviewed-by: Brad Fitzpatrick
+Trust: Damien Neil
+(cherry picked from commit 212d385a2f723a8dd5e7d2e83efb478ddd139349)
+Reviewed-on: https://go-review.googlesource.com/c/go/+/297909
+Trust: Dmitri Shuralyov
+Run-TryBot: Dmitri Shuralyov
+Reviewed-by: Damien Neil
+
+Conflict:NA
+Reference:https://github.com/golang/go/commit/5de8d3bfcb060bbc61b9b9c945055fd3fb5b9607
+
+---
+ src/net/http/transport.go | 13 ++++++---
+ src/net/http/transport_test.go | 51 ++++++++++++++++++++++++++++++++++
+ 2 files changed, 60 insertions(+), 4 deletions(-)
+
+diff --git a/src/net/http/transport.go b/src/net/http/transport.go
+index d37b52b13d..6fb2ea5663 100644
+--- a/src/net/http/transport.go
++++ b/src/net/http/transport.go
+@@ -2560,6 +2560,7 @@ func (pc *persistConn) roundTrip(req *transportRequest) (resp *Response, err err
+ var respHeaderTimer <-chan time.Time
+ cancelChan := req.Request.Cancel
+ ctxDoneChan := req.Context().Done()
++ pcClosed := pc.closech
+ for {
+ testHookWaitResLoop()
+ select {
+@@ -2579,11 +2580,15 @@ func (pc *persistConn) roundTrip(req *transportRequest) (resp *Response, err err
+ defer timer.Stop() // prevent leaks
+ respHeaderTimer = timer.C
+ }
+- case <-pc.closech:
+- if debugRoundTrip {
+- req.logf("closech recv: %T %#v", pc.closed, pc.closed)
++ case <-pcClosed:
++ pcClosed = nil
++ // check if we are still using the connection
++ if pc.t.replaceReqCanceler(req.cancelKey, nil) {
++ if debugRoundTrip {
++ req.logf("closech recv: %T %#v", pc.closed, pc.closed)
++ }
++ return nil, pc.mapRoundTripError(req, startBytesWritten, pc.closed)
+ }
+- return nil, pc.mapRoundTripError(req, startBytesWritten, pc.closed)
+ case <-respHeaderTimer:
+ if debugRoundTrip {
+ req.logf("timeout waiting for response headers.")
+diff --git a/src/net/http/transport_test.go b/src/net/http/transport_test.go
+index 0a47687d9a..3c7b9eb4de 100644
+--- a/src/net/http/transport_test.go
++++ b/src/net/http/transport_test.go
+@@ -6289,3 +6289,54 @@ func TestTransportRejectsSignInContentLength(t *testing.T) {
+ t.Fatalf("Error mismatch\nGot: %q\nWanted substring: %q", got, want)
+ }
+ }
++
++// Issue 41600
++// Test that a new request which uses the connection of an active request
++// cannot cause it to be canceled as well.
++func TestCancelRequestWhenSharingConnection(t *testing.T) {
++ if testing.Short() {
++ t.Skip("skipping in short mode")
++ }
++ ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, req *Request) {
++ w.Header().Add("Content-Length", "0")
++ }))
++ defer ts.Close()
++
++ client := ts.Client()
++ transport := client.Transport.(*Transport)
++ transport.MaxIdleConns = 1
++ transport.MaxConnsPerHost = 1
++
++ var wg sync.WaitGroup
++
++ ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
++
++ for i := 0; i < 10; i++ {
++ wg.Add(1)
++ go func() {
++ defer wg.Done()
++ for ctx.Err() == nil {
++ reqctx, reqcancel := context.WithCancel(ctx)
++ go reqcancel()
++ req, _ := NewRequestWithContext(reqctx, "GET", ts.URL, nil)
++ res, err := client.Do(req)
++ if err == nil {
++ res.Body.Close()
++ }
++ }
++ }()
++ }
++
++ for ctx.Err() == nil {
++ req, _ := NewRequest("GET", ts.URL, nil)
++ if res, err := client.Do(req); err != nil {
++ t.Errorf("unexpected: %p %v", req, err)
++ break
++ } else {
++ res.Body.Close()
++ }
++ }
++
++ cancel()
++ wg.Wait()
++}
+--
+2.27.0
+
diff --git a/0020-release-branch.go1.15-net-http-add-connections-back-.patch b/0020-release-branch.go1.15-net-http-add-connections-back-.patch
new file mode 100644
index 0000000..f3b0198
--- /dev/null
+++ b/0020-release-branch.go1.15-net-http-add-connections-back-.patch
@@ -0,0 +1,129 @@
+From 1c60e0d928764b1b755c494d4a760eb51b99bc90 Mon Sep 17 00:00:00 2001
+From: Michael Fraenkel
+Date: Wed, 2 Dec 2020 17:07:27 -0700
+Subject: [PATCH 20/44] [release-branch.go1.15] net/http: add connections back
+ that haven't been canceled
+
+Issue #41600 fixed the issue when a second request canceled a connection
+while the first request was still in roundTrip.
+This uncovered a second issue where a request was being canceled (in
+roundtrip) but the connection was put back into the idle pool for a
+subsequent request.
+The fix is the similar except its now in readLoop instead of roundTrip.
+A persistent connection is only added back if it successfully removed
+the cancel function; otherwise we know the roundTrip has started
+cancelRequest.
+
+Fixes #42935.
+Updates #42942.
+
+Change-Id: Ia56add20880ccd0c1ab812d380d8628e45f6f44c
+Reviewed-on: https://go-review.googlesource.com/c/go/+/274973
+Trust: Dmitri Shuralyov
+Trust: Damien Neil
+Reviewed-by: Damien Neil
+(cherry picked from commit 854a2f8e01a554d8052445563863775406a04b71)
+Reviewed-on: https://go-review.googlesource.com/c/go/+/297910
+Run-TryBot: Dmitri Shuralyov
+TryBot-Result: Go Bot
+
+Conflict:NA
+Reference:https://github.com/golang/go/commit/1c60e0d928764b1b755c494d4a760eb51b99bc90
+
+---
+ src/net/http/transport.go | 22 ++++++++++++----------
+ 1 file changed, 12 insertions(+), 10 deletions(-)
+
+diff --git a/src/net/http/transport.go b/src/net/http/transport.go
+index 6fb2ea5663..6e430b9885 100644
+--- a/src/net/http/transport.go
++++ b/src/net/http/transport.go
+@@ -766,7 +766,8 @@ func (t *Transport) CancelRequest(req *Request) {
+ }
+
+ // Cancel an in-flight request, recording the error value.
+-func (t *Transport) cancelRequest(key cancelKey, err error) {
++// Returns whether the request was canceled.
++func (t *Transport) cancelRequest(key cancelKey, err error) bool {
+ t.reqMu.Lock()
+ cancel := t.reqCanceler[key]
+ delete(t.reqCanceler, key)
+@@ -774,6 +775,8 @@ func (t *Transport) cancelRequest(key cancelKey, err error) {
+ if cancel != nil {
+ cancel(err)
+ }
++
++ return cancel != nil
+ }
+
+ //
+@@ -2087,18 +2090,17 @@ func (pc *persistConn) readLoop() {
+ }
+
+ if !hasBody || bodyWritable {
+- pc.t.setReqCanceler(rc.cancelKey, nil)
++ replaced := pc.t.replaceReqCanceler(rc.cancelKey, nil)
+
+ // Put the idle conn back into the pool before we send the response
+ // so if they process it quickly and make another request, they'll
+ // get this same conn. But we use the unbuffered channel 'rc'
+ // to guarantee that persistConn.roundTrip got out of its select
+ // potentially waiting for this persistConn to close.
+- // but after
+ alive = alive &&
+ !pc.sawEOF &&
+ pc.wroteRequest() &&
+- tryPutIdleConn(trace)
++ replaced && tryPutIdleConn(trace)
+
+ if bodyWritable {
+ closeErr = errCallerOwnsConn
+@@ -2160,12 +2162,12 @@ func (pc *persistConn) readLoop() {
+ // reading the response body. (or for cancellation or death)
+ select {
+ case bodyEOF := <-waitForBodyRead:
+- pc.t.setReqCanceler(rc.cancelKey, nil) // before pc might return to idle pool
++ replaced := pc.t.replaceReqCanceler(rc.cancelKey, nil) // before pc might return to idle pool
+ alive = alive &&
+ bodyEOF &&
+ !pc.sawEOF &&
+ pc.wroteRequest() &&
+- tryPutIdleConn(trace)
++ replaced && tryPutIdleConn(trace)
+ if bodyEOF {
+ eofc <- struct{}{}
+ }
+@@ -2561,6 +2563,7 @@ func (pc *persistConn) roundTrip(req *transportRequest) (resp *Response, err err
+ cancelChan := req.Request.Cancel
+ ctxDoneChan := req.Context().Done()
+ pcClosed := pc.closech
++ canceled := false
+ for {
+ testHookWaitResLoop()
+ select {
+@@ -2582,8 +2585,7 @@ func (pc *persistConn) roundTrip(req *transportRequest) (resp *Response, err err
+ }
+ case <-pcClosed:
+ pcClosed = nil
+- // check if we are still using the connection
+- if pc.t.replaceReqCanceler(req.cancelKey, nil) {
++ if canceled || pc.t.replaceReqCanceler(req.cancelKey, nil) {
+ if debugRoundTrip {
+ req.logf("closech recv: %T %#v", pc.closed, pc.closed)
+ }
+@@ -2607,10 +2609,10 @@ func (pc *persistConn) roundTrip(req *transportRequest) (resp *Response, err err
+ }
+ return re.res, nil
+ case <-cancelChan:
+- pc.t.cancelRequest(req.cancelKey, errRequestCanceled)
++ canceled = pc.t.cancelRequest(req.cancelKey, errRequestCanceled)
+ cancelChan = nil
+ case <-ctxDoneChan:
+- pc.t.cancelRequest(req.cancelKey, req.Context().Err())
++ canceled = pc.t.cancelRequest(req.cancelKey, req.Context().Err())
+ cancelChan = nil
+ ctxDoneChan = nil
+ }
+--
+2.27.0
+
diff --git a/0001-release-branch.go1.15-security-encoding-xml-prevent-.patch b/0021-release-branch.go1.15-security-encoding-xml-prevent-.patch
similarity index 96%
rename from 0001-release-branch.go1.15-security-encoding-xml-prevent-.patch
rename to 0021-release-branch.go1.15-security-encoding-xml-prevent-.patch
index abaee05..294539e 100644
--- a/0001-release-branch.go1.15-security-encoding-xml-prevent-.patch
+++ b/0021-release-branch.go1.15-security-encoding-xml-prevent-.patch
@@ -1,7 +1,7 @@
From 91062c2e4cbbf78a108919f6ed3ded1173937cf3 Mon Sep 17 00:00:00 2001
From: Katie Hockman
Date: Mon, 1 Mar 2021 09:54:00 -0500
-Subject: [PATCH] [release-branch.go1.15-security] encoding/xml: prevent
+Subject: [PATCH 21/44] [release-branch.go1.15-security] encoding/xml: prevent
infinite loop while decoding
This change properly handles a TokenReader which
@@ -19,6 +19,10 @@ Reviewed-by: Roland Shoemaker
Reviewed-by: Filippo Valsorda
(cherry picked from commit e7ce1f6746223ec7b4caa3b1ece25d9be3864710)
Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/1014236
+
+Conflict:NA
+Reference:https://github.com/golang/go/commit/91062c2e4cbbf78a108919f6ed3ded1173937cf3
+
---
src/encoding/xml/xml.go | 19 ++++---
src/encoding/xml/xml_test.go | 104 +++++++++++++++++++++++++++--------
diff --git a/0023-release-branch.go1.15-cmd-go-don-t-report-missing-st.patch b/0023-release-branch.go1.15-cmd-go-don-t-report-missing-st.patch
new file mode 100644
index 0000000..71642c7
--- /dev/null
+++ b/0023-release-branch.go1.15-cmd-go-don-t-report-missing-st.patch
@@ -0,0 +1,121 @@
+From ba3dc70dc5c9f2162024b09d6b13bda1f4575b01 Mon Sep 17 00:00:00 2001
+From: Jay Conrod
+Date: Thu, 4 Mar 2021 11:50:31 -0500
+Subject: [PATCH 23/44] [release-branch.go1.15] cmd/go: don't report missing
+ std import errors for tidy and vendor
+
+'go mod tidy' and 'go mod vendor' normally report errors when a
+package can't be imported, even if the import appears in a file that
+wouldn't be compiled by the current version of Go. These errors are
+common for packages introduced in higher versions of Go, like "embed"
+in 1.16.
+
+This change causes 'go mod tidy' and 'go mod vendor' to ignore
+missing package errors if the import path appears to come from the
+standard library because it lacks a dot in the first path element.
+
+NOTE: This change is not a clean cherry-pick of CL 298749 because
+parts of modload were substantially rewritten after 1.15.
+
+Fixes #44792
+Updates #27063
+
+Change-Id: I61d6443e77ab95fd8c0d1514f57ef4c8885a77cc
+Reviewed-on: https://go-review.googlesource.com/c/go/+/298749
+Trust: Jay Conrod
+Run-TryBot: Jay Conrod
+Reviewed-by: Bryan C. Mills
+TryBot-Result: Go Bot
+(cherry picked from commit 56d52e661114be60fb1893b034ac0c5976b622af)
+Reviewed-on: https://go-review.googlesource.com/c/go/+/298950
+
+Conflict:NA
+Reference:https://github.com/golang/go/commit/ba3dc70dc5c9f2162024b09d6b13bda1f4575b01
+
+---
+ src/cmd/go/internal/modcmd/tidy.go | 1 +
+ src/cmd/go/internal/modcmd/vendor.go | 1 +
+ src/cmd/go/internal/modload/init.go | 6 ++++++
+ src/cmd/go/internal/modload/load.go | 5 +++++
+ src/cmd/go/testdata/script/mod_tidy_error.txt | 4 ++--
+ 5 files changed, 15 insertions(+), 2 deletions(-)
+
+diff --git a/src/cmd/go/internal/modcmd/tidy.go b/src/cmd/go/internal/modcmd/tidy.go
+index af2b04c0c2..5ff847485c 100644
+--- a/src/cmd/go/internal/modcmd/tidy.go
++++ b/src/cmd/go/internal/modcmd/tidy.go
+@@ -42,6 +42,7 @@ func runTidy(cmd *base.Command, args []string) {
+ base.Fatalf("go mod tidy: no arguments allowed")
+ }
+
++ modload.SilenceMissingStdImports = true
+ modload.LoadALL()
+ modload.TidyBuildList()
+ modTidyGoSum() // updates memory copy; WriteGoMod on next line flushes it out
+diff --git a/src/cmd/go/internal/modcmd/vendor.go b/src/cmd/go/internal/modcmd/vendor.go
+index 8509ceb7a8..5a5bb943a5 100644
+--- a/src/cmd/go/internal/modcmd/vendor.go
++++ b/src/cmd/go/internal/modcmd/vendor.go
+@@ -47,6 +47,7 @@ func runVendor(cmd *base.Command, args []string) {
+ if len(args) != 0 {
+ base.Fatalf("go mod vendor: vendor takes no arguments")
+ }
++ modload.SilenceMissingStdImports = true
+ pkgs := modload.LoadVendor()
+
+ vdir := filepath.Join(modload.ModRoot(), "vendor")
+diff --git a/src/cmd/go/internal/modload/init.go b/src/cmd/go/internal/modload/init.go
+index 664a2a1594..2360feef04 100644
+--- a/src/cmd/go/internal/modload/init.go
++++ b/src/cmd/go/internal/modload/init.go
+@@ -56,6 +56,12 @@ var (
+ CmdModModule string // module argument for 'go mod init'
+
+ allowMissingModuleImports bool
++
++ // SilenceMissingStdImports indicates that LoadALL should not print an error
++ // or terminate the process if an imported package is missing, and the import
++ // path looks like it might be in the standard library (perhaps in a future
++ // Go version).
++ SilenceMissingStdImports bool
+ )
+
+ // ModFile returns the parsed go.mod file.
+diff --git a/src/cmd/go/internal/modload/load.go b/src/cmd/go/internal/modload/load.go
+index 30992e0cc2..e5ea1a6c23 100644
+--- a/src/cmd/go/internal/modload/load.go
++++ b/src/cmd/go/internal/modload/load.go
+@@ -433,6 +433,11 @@ func loadAll(testAll bool) []string {
+ var paths []string
+ for _, pkg := range loaded.pkgs {
+ if pkg.err != nil {
++ if impErr := (*ImportMissingError)(nil); SilenceMissingStdImports &&
++ errors.As(pkg.err, &impErr) &&
++ search.IsStandardImportPath(impErr.Path) {
++ continue
++ }
+ base.Errorf("%s: %v", pkg.stackText(), pkg.err)
+ continue
+ }
+diff --git a/src/cmd/go/testdata/script/mod_tidy_error.txt b/src/cmd/go/testdata/script/mod_tidy_error.txt
+index b6c24ceaf7..395537b1a7 100644
+--- a/src/cmd/go/testdata/script/mod_tidy_error.txt
++++ b/src/cmd/go/testdata/script/mod_tidy_error.txt
+@@ -4,12 +4,12 @@ env GO111MODULE=on
+ # 'go mod tidy' and 'go mod vendor' should not hide loading errors.
+
+ ! go mod tidy
+-stderr '^issue27063 imports\n\tnonexist: package nonexist is not in GOROOT \(.*\)'
++! stderr 'package nonexist is not in GOROOT'
+ stderr '^issue27063 imports\n\tnonexist.example.com: cannot find module providing package nonexist.example.com'
+ stderr '^issue27063 imports\n\tissue27063/other imports\n\tother.example.com/nonexist: cannot find module providing package other.example.com/nonexist'
+
+ ! go mod vendor
+-stderr '^issue27063 imports\n\tnonexist: package nonexist is not in GOROOT \(.*\)'
++! stderr 'package nonexist is not in GOROOT'
+ stderr '^issue27063 imports\n\tnonexist.example.com: cannot find module providing package nonexist.example.com'
+ stderr '^issue27063 imports\n\tissue27063/other imports\n\tother.example.com/nonexist: cannot find module providing package other.example.com/nonexist'
+
+--
+2.27.0
+
diff --git a/0025-release-branch.go1.15-cmd-go-internal-modfetch-detec.patch b/0025-release-branch.go1.15-cmd-go-internal-modfetch-detec.patch
new file mode 100644
index 0000000..9cf8ece
--- /dev/null
+++ b/0025-release-branch.go1.15-cmd-go-internal-modfetch-detec.patch
@@ -0,0 +1,310 @@
+From 7038a380bcd0183842471c1984da491e044d3d34 Mon Sep 17 00:00:00 2001
+From: Jay Conrod
+Date: Wed, 3 Mar 2021 16:30:22 -0500
+Subject: [PATCH 25/44] [release-branch.go1.15] cmd/go/internal/modfetch:
+ detect and recover from missing ziphash file
+
+Previously, if an extracted module directory existed in the module
+cache, but the corresponding ziphash file did not, if the sum was
+missing from go.sum, we would not verify the sum. This caused 'go get'
+not to write missing sums. 'go build' in readonly mode (now the
+default) checks for missing sums and doesn't attempt to fetch modules
+that can't be verified against go.sum.
+
+With this change, when requesting the module directory with
+modfetch.DownloadDir, if the ziphash file is missing, the go command
+will re-hash the zip without downloading or re-extracting it again.
+
+Note that the go command creates the ziphash file before the module
+directory, but another program could remove it separately, and it
+might not be present after a crash.
+
+Fixes #44872
+
+Change-Id: I64551e048a3ba17d069de1ec123d5b8b2757543c
+Reviewed-on: https://go-review.googlesource.com/c/go/+/298352
+Trust: Jay Conrod
+Run-TryBot: Jay Conrod
+TryBot-Result: Go Bot
+Reviewed-by: Bryan C. Mills
+(cherry picked from commit 302a400316319501748c0f034464fa70e7815272)
+Reviewed-on: https://go-review.googlesource.com/c/go/+/299830
+
+Conflict:NA
+Reference:https://github.com/golang/go/commit/7038a380bcd0183842471c1984da491e044d3d34
+
+---
+ src/cmd/go/internal/modfetch/cache.go | 17 ++++
+ src/cmd/go/internal/modfetch/fetch.go | 77 ++++++++++++-------
+ .../script/mod_get_missing_ziphash.txt | 55 +++++++++++++
+ src/cmd/go/testdata/script/mod_verify.txt | 7 +-
+ 4 files changed, 125 insertions(+), 31 deletions(-)
+ create mode 100644 src/cmd/go/testdata/script/mod_get_missing_ziphash.txt
+
+diff --git a/src/cmd/go/internal/modfetch/cache.go b/src/cmd/go/internal/modfetch/cache.go
+index e3074b775e..0b64a6943b 100644
+--- a/src/cmd/go/internal/modfetch/cache.go
++++ b/src/cmd/go/internal/modfetch/cache.go
+@@ -83,6 +83,7 @@ func DownloadDir(m module.Version) (string, error) {
+ return "", err
+ }
+
++ // Check whether the directory itself exists.
+ dir := filepath.Join(cfg.GOMODCACHE, enc+"@"+encVer)
+ if fi, err := os.Stat(dir); os.IsNotExist(err) {
+ return dir, err
+@@ -91,6 +92,9 @@ func DownloadDir(m module.Version) (string, error) {
+ } else if !fi.IsDir() {
+ return dir, &DownloadDirPartialError{dir, errors.New("not a directory")}
+ }
++
++ // Check if a .partial file exists. This is created at the beginning of
++ // a download and removed after the zip is extracted.
+ partialPath, err := CachePath(m, "partial")
+ if err != nil {
+ return dir, err
+@@ -100,6 +104,19 @@ func DownloadDir(m module.Version) (string, error) {
+ } else if !os.IsNotExist(err) {
+ return dir, err
+ }
++
++ // Check if a .ziphash file exists. It should be created before the
++ // zip is extracted, but if it was deleted (by another program?), we need
++ // to re-calculate it.
++ ziphashPath, err := CachePath(m, "ziphash")
++ if err != nil {
++ return dir, err
++ }
++ if _, err := os.Stat(ziphashPath); os.IsNotExist(err) {
++ return dir, &DownloadDirPartialError{dir, errors.New("ziphash file is missing")}
++ } else if err != nil {
++ return dir, err
++ }
+ return dir, nil
+ }
+
+diff --git a/src/cmd/go/internal/modfetch/fetch.go b/src/cmd/go/internal/modfetch/fetch.go
+index fd7a5cef83..6a6c972157 100644
+--- a/src/cmd/go/internal/modfetch/fetch.go
++++ b/src/cmd/go/internal/modfetch/fetch.go
+@@ -206,13 +206,16 @@ func DownloadZip(mod module.Version) (zipfile string, err error) {
+ if err != nil {
+ return cached{"", err}
+ }
++ ziphashfile := zipfile + "hash"
+
+- // Skip locking if the zipfile already exists.
++ // Return without locking if the zip and ziphash files exist.
+ if _, err := os.Stat(zipfile); err == nil {
+- return cached{zipfile, nil}
++ if _, err := os.Stat(ziphashfile); err == nil {
++ return cached{zipfile, nil}
++ }
+ }
+
+- // The zip file does not exist. Acquire the lock and create it.
++ // The zip or ziphash file does not exist. Acquire the lock and create them.
+ if cfg.CmdName != "mod download" {
+ fmt.Fprintf(os.Stderr, "go: downloading %s %s\n", mod.Path, mod.Version)
+ }
+@@ -222,14 +225,6 @@ func DownloadZip(mod module.Version) (zipfile string, err error) {
+ }
+ defer unlock()
+
+- // Double-check that the zipfile was not created while we were waiting for
+- // the lock.
+- if _, err := os.Stat(zipfile); err == nil {
+- return cached{zipfile, nil}
+- }
+- if err := os.MkdirAll(filepath.Dir(zipfile), 0777); err != nil {
+- return cached{"", err}
+- }
+ if err := downloadZip(mod, zipfile); err != nil {
+ return cached{"", err}
+ }
+@@ -239,6 +234,25 @@ func DownloadZip(mod module.Version) (zipfile string, err error) {
+ }
+
+ func downloadZip(mod module.Version, zipfile string) (err error) {
++ // Double-check that the zipfile was not created while we were waiting for
++ // the lock in DownloadZip.
++ ziphashfile := zipfile + "hash"
++ var zipExists, ziphashExists bool
++ if _, err := os.Stat(zipfile); err == nil {
++ zipExists = true
++ }
++ if _, err := os.Stat(ziphashfile); err == nil {
++ ziphashExists = true
++ }
++ if zipExists && ziphashExists {
++ return nil
++ }
++
++ // Create parent directories.
++ if err := os.MkdirAll(filepath.Dir(zipfile), 0777); err != nil {
++ return err
++ }
++
+ // Clean up any remaining tempfiles from previous runs.
+ // This is only safe to do because the lock file ensures that their
+ // writers are no longer active.
+@@ -250,6 +264,12 @@ func downloadZip(mod module.Version, zipfile string) (err error) {
+ }
+ }
+
++ // If the zip file exists, the ziphash file must have been deleted
++ // or lost after a file system crash. Re-hash the zip without downloading.
++ if zipExists {
++ return hashZip(mod, zipfile, ziphashfile)
++ }
++
+ // From here to the os.Rename call below is functionally almost equivalent to
+ // renameio.WriteToFile, with one key difference: we want to validate the
+ // contents of the file (by hashing it) before we commit it. Because the file
+@@ -306,15 +326,7 @@ func downloadZip(mod module.Version, zipfile string) (err error) {
+ }
+
+ // Hash the zip file and check the sum before renaming to the final location.
+- hash, err := dirhash.HashZip(f.Name(), dirhash.DefaultHash)
+- if err != nil {
+- return err
+- }
+- if err := checkModSum(mod, hash); err != nil {
+- return err
+- }
+-
+- if err := renameio.WriteFile(zipfile+"hash", []byte(hash), 0666); err != nil {
++ if err := hashZip(mod, f.Name(), ziphashfile); err != nil {
+ return err
+ }
+ if err := os.Rename(f.Name(), zipfile); err != nil {
+@@ -326,6 +338,22 @@ func downloadZip(mod module.Version, zipfile string) (err error) {
+ return nil
+ }
+
++// hashZip reads the zip file opened in f, then writes the hash to ziphashfile,
++// overwriting that file if it exists.
++//
++// If the hash does not match go.sum (or the sumdb if enabled), hashZip returns
++// an error and does not write ziphashfile.
++func hashZip(mod module.Version, zipfile, ziphashfile string) error {
++ hash, err := dirhash.HashZip(zipfile, dirhash.DefaultHash)
++ if err != nil {
++ return err
++ }
++ if err := checkModSum(mod, hash); err != nil {
++ return err
++ }
++ return renameio.WriteFile(ziphashfile, []byte(hash), 0666)
++}
++
+ // makeDirsReadOnly makes a best-effort attempt to remove write permissions for dir
+ // and its transitive contents.
+ func makeDirsReadOnly(dir string) {
+@@ -457,11 +485,6 @@ func readGoSum(dst map[module.Version][]string, file string, data []byte) error
+
+ // checkMod checks the given module's checksum.
+ func checkMod(mod module.Version) {
+- if cfg.GOMODCACHE == "" {
+- // Do not use current directory.
+- return
+- }
+-
+ // Do the file I/O before acquiring the go.sum lock.
+ ziphash, err := CachePath(mod, "ziphash")
+ if err != nil {
+@@ -469,10 +492,6 @@ func checkMod(mod module.Version) {
+ }
+ data, err := renameio.ReadFile(ziphash)
+ if err != nil {
+- if errors.Is(err, os.ErrNotExist) {
+- // This can happen if someone does rm -rf GOPATH/src/cache/download. So it goes.
+- return
+- }
+ base.Fatalf("verifying %v", module.VersionError(mod, err))
+ }
+ h := strings.TrimSpace(string(data))
+diff --git a/src/cmd/go/testdata/script/mod_get_missing_ziphash.txt b/src/cmd/go/testdata/script/mod_get_missing_ziphash.txt
+new file mode 100644
+index 0000000000..afb5d2e844
+--- /dev/null
++++ b/src/cmd/go/testdata/script/mod_get_missing_ziphash.txt
+@@ -0,0 +1,55 @@
++# Test that if the module cache contains an extracted source directory but not
++# a ziphash, 'go build' complains about a missing sum, and 'go get' adds
++# the sum. Verifies #44749.
++
++# With a tidy go.sum, go build succeeds. This also populates the module cache.
++cp go.sum.tidy go.sum
++go build -n use
++env GOPROXY=off
++env GOSUMDB=off
++
++# Control case: if we delete the hash for rsc.io/quote v1.5.2,
++# 'go build' reports an error. 'go get' adds the sum.
++cp go.sum.bug go.sum
++! go build -n -mod=readonly use
++stderr '^go: updates to go.sum needed, disabled by -mod=readonly$'
++go get -d use
++cmp go.sum go.sum.tidy
++go build -n use
++
++# If we delete the hash *and* the ziphash file, we should see the same behavior.
++cp go.sum.bug go.sum
++rm $WORK/gopath/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.2.ziphash
++! go build -n -mod=readonly use
++stderr '^go: updates to go.sum needed, disabled by -mod=readonly$'
++go get -d use
++cmp go.sum go.sum.tidy
++go build -n use
++
++-- go.mod --
++module use
++
++go 1.17
++
++require rsc.io/quote v1.5.2
++-- go.sum.tidy --
++golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c h1:pvCbr/wm8HzDD3fVywevekufpn6tCGPY3spdHeZJEsw=
++golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
++rsc.io/quote v1.5.2 h1:3fEykkD9k7lYzXqCYrwGAf7iNhbk4yCjHmKBN9td4L0=
++rsc.io/quote v1.5.2/go.mod h1:LzX7hefJvL54yjefDEDHNONDjII0t9xZLPXsUe+TKr0=
++rsc.io/sampler v1.3.0 h1:HLGR/BgEtI3r0uymSP/nl2uPLsUnNJX8toRyhfpBTII=
++rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
++rsc.io/testonly v1.0.0 h1:K/VWHdO+Jv7woUXG0GzVNx1czBXUt3Ib1deaMn+xk64=
++rsc.io/testonly v1.0.0/go.mod h1:OqmGbIFOcF+XrFReLOGZ6BhMM7uMBiQwZsyNmh74SzY=
++-- go.sum.bug --
++golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c h1:pvCbr/wm8HzDD3fVywevekufpn6tCGPY3spdHeZJEsw=
++golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
++rsc.io/quote v1.5.2/go.mod h1:LzX7hefJvL54yjefDEDHNONDjII0t9xZLPXsUe+TKr0=
++rsc.io/sampler v1.3.0 h1:HLGR/BgEtI3r0uymSP/nl2uPLsUnNJX8toRyhfpBTII=
++rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
++rsc.io/testonly v1.0.0 h1:K/VWHdO+Jv7woUXG0GzVNx1czBXUt3Ib1deaMn+xk64=
++rsc.io/testonly v1.0.0/go.mod h1:OqmGbIFOcF+XrFReLOGZ6BhMM7uMBiQwZsyNmh74SzY=
++-- use.go --
++package use
++
++import _ "rsc.io/quote"
+diff --git a/src/cmd/go/testdata/script/mod_verify.txt b/src/cmd/go/testdata/script/mod_verify.txt
+index 646bc62bb7..7163d1a64b 100644
+--- a/src/cmd/go/testdata/script/mod_verify.txt
++++ b/src/cmd/go/testdata/script/mod_verify.txt
+@@ -50,10 +50,13 @@ go mod tidy
+ grep '^rsc.io/quote v1.1.0/go.mod ' go.sum
+ grep '^rsc.io/quote v1.1.0 ' go.sum
+
+-# sync should ignore missing ziphash; verify should not
++# verify should fail on a missing ziphash. tidy should restore it.
+ rm $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.1.0.ziphash
+-go mod tidy
+ ! go mod verify
++stderr '^rsc.io/quote v1.1.0: missing ziphash: open '$GOPATH'[/\\]pkg[/\\]mod[/\\]cache[/\\]download[/\\]rsc.io[/\\]quote[/\\]@v[/\\]v1.1.0.ziphash'
++go mod tidy
++exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.1.0.ziphash
++go mod verify
+
+ # Packages below module root should not be mentioned in go.sum.
+ rm go.sum
+--
+2.27.0
+
diff --git a/0026-release-branch.go1.15-cmd-link-generate-trampoline-f.patch b/0026-release-branch.go1.15-cmd-link-generate-trampoline-f.patch
new file mode 100644
index 0000000..5a6ef3e
--- /dev/null
+++ b/0026-release-branch.go1.15-cmd-link-generate-trampoline-f.patch
@@ -0,0 +1,133 @@
+From 7c88ae4117c16c1e5b80189b81d67845e1c40d9d Mon Sep 17 00:00:00 2001
+From: Cherry Zhang
+Date: Tue, 16 Feb 2021 10:20:58 -0500
+Subject: [PATCH 26/44] [release-branch.go1.15] cmd/link: generate trampoline
+ for inter-dependent packages
+
+Currently, in the trampoline generation pass we expect packages
+are laid out in dependency order, so a cross-package jump always
+has a known target address so we can check if a trampoline is
+needed. With linknames, there can be cycles in the package
+dependency graph, making this algorithm no longer work. For them,
+as the target address is unkown we conservatively generate a
+trampoline. This may generate unnecessary trampolines (if the
+packages turn out laid together), but package cycles are extremely
+rare so this is fine.
+
+Updates #44639.
+Fixes #44748.
+
+Change-Id: I2dc2998edacbda27d726fc79452313a21d07787a
+Reviewed-on: https://go-review.googlesource.com/c/go/+/292490
+Trust: Cherry Zhang
+Reviewed-by: Than McIntosh
+(cherry picked from commit 098504c73ff6ece19566a1ac811ceed73be7c81d)
+Reviewed-on: https://go-review.googlesource.com/c/go/+/298030
+Run-TryBot: Cherry Zhang
+TryBot-Result: Go Bot
+
+Conflict:NA
+Reference:https://github.com/golang/go/commit/7c88ae4117c16c1e5b80189b81d67845e1c40d9d
+
+---
+ src/cmd/link/internal/arm/asm.go | 16 +++++++++++-----
+ src/cmd/link/internal/ld/data.go | 12 +++++-------
+ src/cmd/link/internal/ppc64/asm.go | 12 +++++++++---
+ 3 files changed, 25 insertions(+), 15 deletions(-)
+
+diff --git a/src/cmd/link/internal/arm/asm.go b/src/cmd/link/internal/arm/asm.go
+index 903e62108e..43643341d2 100644
+--- a/src/cmd/link/internal/arm/asm.go
++++ b/src/cmd/link/internal/arm/asm.go
+@@ -373,10 +373,16 @@ func trampoline(ctxt *ld.Link, ldr *loader.Loader, ri int, rs, s loader.Sym) {
+ r := relocs.At2(ri)
+ switch r.Type() {
+ case objabi.R_CALLARM:
+- // r.Add is the instruction
+- // low 24-bit encodes the target address
+- t := (ldr.SymValue(rs) + int64(signext24(r.Add()&0xffffff)*4) - (ldr.SymValue(s) + int64(r.Off()))) / 4
+- if t > 0x7fffff || t < -0x800000 || (*ld.FlagDebugTramp > 1 && ldr.SymPkg(s) != ldr.SymPkg(rs)) {
++ var t int64
++ // ldr.SymValue(rs) == 0 indicates a cross-package jump to a function that is not yet
++ // laid out. Conservatively use a trampoline. This should be rare, as we lay out packages
++ // in dependency order.
++ if ldr.SymValue(rs) != 0 {
++ // r.Add is the instruction
++ // low 24-bit encodes the target address
++ t = (ldr.SymValue(rs) + int64(signext24(r.Add()&0xffffff)*4) - (ldr.SymValue(s) + int64(r.Off()))) / 4
++ }
++ if t > 0x7fffff || t < -0x800000 || ldr.SymValue(rs) == 0 || (*ld.FlagDebugTramp > 1 && ldr.SymPkg(s) != ldr.SymPkg(rs)) {
+ // direct call too far, need to insert trampoline.
+ // look up existing trampolines first. if we found one within the range
+ // of direct call, we can reuse it. otherwise create a new one.
+@@ -447,7 +453,7 @@ func gentramp(arch *sys.Arch, linkmode ld.LinkMode, ldr *loader.Loader, tramp *l
+ arch.ByteOrder.PutUint32(P[8:], o3)
+ tramp.SetData(P)
+
+- if linkmode == ld.LinkExternal {
++ if linkmode == ld.LinkExternal || ldr.SymValue(target) == 0 {
+ r := loader.Reloc{
+ Off: 8,
+ Type: objabi.R_ADDR,
+diff --git a/src/cmd/link/internal/ld/data.go b/src/cmd/link/internal/ld/data.go
+index d3f308c8fa..2b55a5f6fc 100644
+--- a/src/cmd/link/internal/ld/data.go
++++ b/src/cmd/link/internal/ld/data.go
+@@ -105,14 +105,12 @@ func trampoline(ctxt *Link, s loader.Sym) {
+ }
+ rs = ldr.ResolveABIAlias(rs)
+ if ldr.SymValue(rs) == 0 && (ldr.SymType(rs) != sym.SDYNIMPORT && ldr.SymType(rs) != sym.SUNDEFEXT) {
+- if ldr.SymPkg(rs) != ldr.SymPkg(s) {
+- if !isRuntimeDepPkg(ldr.SymPkg(s)) || !isRuntimeDepPkg(ldr.SymPkg(rs)) {
+- ctxt.Errorf(s, "unresolved inter-package jump to %s(%s) from %s", ldr.SymName(rs), ldr.SymPkg(rs), ldr.SymPkg(s))
+- }
+- // runtime and its dependent packages may call to each other.
+- // they are fine, as they will be laid down together.
++ if ldr.SymPkg(rs) == ldr.SymPkg(s) {
++ continue // symbols in the same package are laid out together
++ }
++ if isRuntimeDepPkg(ldr.SymPkg(s)) && isRuntimeDepPkg(ldr.SymPkg(rs)) {
++ continue // runtime packages are laid out together
+ }
+- continue
+ }
+
+ thearch.Trampoline(ctxt, ldr, ri, rs, s)
+diff --git a/src/cmd/link/internal/ppc64/asm.go b/src/cmd/link/internal/ppc64/asm.go
+index b1c0873d7a..a3ecd43f89 100644
+--- a/src/cmd/link/internal/ppc64/asm.go
++++ b/src/cmd/link/internal/ppc64/asm.go
+@@ -672,13 +672,19 @@ func trampoline(ctxt *ld.Link, ldr *loader.Loader, ri int, rs, s loader.Sym) {
+
+ relocs := ldr.Relocs(s)
+ r := relocs.At2(ri)
+- t := ldr.SymValue(rs) + r.Add() - (ldr.SymValue(s) + int64(r.Off()))
++ var t int64
++ // ldr.SymValue(rs) == 0 indicates a cross-package jump to a function that is not yet
++ // laid out. Conservatively use a trampoline. This should be rare, as we lay out packages
++ // in dependency order.
++ if ldr.SymValue(rs) != 0 {
++ t = ldr.SymValue(rs) + r.Add() - (ldr.SymValue(s) + int64(r.Off()))
++ }
+ switch r.Type() {
+ case objabi.R_CALLPOWER:
+
+ // If branch offset is too far then create a trampoline.
+
+- if (ctxt.IsExternal() && ldr.SymSect(s) != ldr.SymSect(rs)) || (ctxt.IsInternal() && int64(int32(t<<6)>>6) != t) || (*ld.FlagDebugTramp > 1 && ldr.SymPkg(s) != ldr.SymPkg(rs)) {
++ if (ctxt.IsExternal() && ldr.SymSect(s) != ldr.SymSect(rs)) || (ctxt.IsInternal() && int64(int32(t<<6)>>6) != t) || ldr.SymValue(rs) == 0 || (*ld.FlagDebugTramp > 1 && ldr.SymPkg(s) != ldr.SymPkg(rs)) {
+ var tramp loader.Sym
+ for i := 0; ; i++ {
+
+@@ -769,7 +775,7 @@ func gentramp(ctxt *ld.Link, ldr *loader.Loader, tramp *loader.SymbolBuilder, ta
+
+ // With external linking, the target address must be
+ // relocated using LO and HA
+- if ctxt.IsExternal() {
++ if ctxt.IsExternal() || ldr.SymValue(target) == 0 {
+ r := loader.Reloc{
+ Off: 0,
+ Type: objabi.R_ADDRPOWER,
+--
+2.27.0
+
diff --git a/0027-release-branch.go1.15-net-http-update-bundled-x-net-.patch b/0027-release-branch.go1.15-net-http-update-bundled-x-net-.patch
new file mode 100644
index 0000000..a619629
--- /dev/null
+++ b/0027-release-branch.go1.15-net-http-update-bundled-x-net-.patch
@@ -0,0 +1,49 @@
+From 69b943102868747ff2b62d9ada02c464d9984aef Mon Sep 17 00:00:00 2001
+From: Dmitri Shuralyov
+Date: Mon, 29 Mar 2021 11:19:23 -0400
+Subject: [PATCH 27/44] [release-branch.go1.15] net/http: update bundled
+ x/net/http2
+
+Bring in the change in CL 304309 with:
+
+ go mod edit -replace=golang.org/x/net=golang.org/x/net@release-branch.go1.15-bundle
+ GOFLAGS='-mod=mod' go generate -run=bundle std
+ go mod edit -dropreplace=golang.org/x/net
+ go get -d golang.org/x/net@release-branch.go1.15
+ go mod tidy
+ go mod vendor
+
+For #45076.
+Updates #40213.
+
+Change-Id: I68d5e1f2394508c9cf8627fb852dd9e906d45016
+Reviewed-on: https://go-review.googlesource.com/c/go/+/305489
+Trust: Dmitri Shuralyov
+Trust: Emmanuel Odeke
+Run-TryBot: Dmitri Shuralyov
+Reviewed-by: Emmanuel Odeke
+TryBot-Result: Go Bot
+
+Conflict:NA
+Reference:https://github.com/golang/go/commit/69b943102868747ff2b62d9ada02c464d9984aef
+
+---
+ src/net/http/h2_bundle.go | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/src/net/http/h2_bundle.go b/src/net/http/h2_bundle.go
+index 678c6eb9d4..3d83084702 100644
+--- a/src/net/http/h2_bundle.go
++++ b/src/net/http/h2_bundle.go
+@@ -8985,6 +8985,8 @@ func http2strSliceContains(ss []string, s string) bool {
+
+ type http2erringRoundTripper struct{ err error }
+
++func (rt http2erringRoundTripper) RoundTripErr() error { return rt.err }
++
+ func (rt http2erringRoundTripper) RoundTrip(*Request) (*Response, error) { return nil, rt.err }
+
+ // gzipReader wraps a response body so it can lazily
+--
+2.27.0
+
diff --git a/0028-release-branch.go1.15-net-http-fix-detection-of-Roun.patch b/0028-release-branch.go1.15-net-http-fix-detection-of-Roun.patch
new file mode 100644
index 0000000..ecd987a
--- /dev/null
+++ b/0028-release-branch.go1.15-net-http-fix-detection-of-Roun.patch
@@ -0,0 +1,81 @@
+From be872812063f29e9c0d280fb37289d40330d96db Mon Sep 17 00:00:00 2001
+From: Michael Fraenkel
+Date: Thu, 16 Jul 2020 21:30:12 -0600
+Subject: [PATCH 28/44] [release-branch.go1.15] net/http: fix detection of
+ Roundtrippers that always error
+
+CL 220905 added code to identify alternate transports that always error
+by using http2erringRoundTripper. This does not work when the transport
+is from another package, e.g., http2.erringRoundTripper.
+Expose a new method that allow detection of such a RoundTripper.
+Switch to an interface that is both a RoundTripper and can return the
+underlying error.
+
+Fixes #45076.
+Updates #40213.
+
+Change-Id: I170739857ab9e99dffb5fa55c99b24b23c2f9c54
+Reviewed-on: https://go-review.googlesource.com/c/go/+/243258
+Reviewed-by: Emmanuel Odeke
+Run-TryBot: Emmanuel Odeke
+TryBot-Result: Gobot Gobot
+Reviewed-on: https://go-review.googlesource.com/c/go/+/304210
+Trust: Dmitri Shuralyov
+Trust: Emmanuel Odeke
+Run-TryBot: Dmitri Shuralyov
+TryBot-Result: Go Bot
+Reviewed-by: Emmanuel Odeke
+
+Conflict:NA
+Reference:https://github.com/golang/go/commit/be872812063f29e9c0d280fb37289d40330d96db
+
+---
+ src/net/http/omithttp2.go | 4 ----
+ src/net/http/transport.go | 8 ++++++--
+ 2 files changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/src/net/http/omithttp2.go b/src/net/http/omithttp2.go
+index 7e2f492579..c8f5c28a59 100644
+--- a/src/net/http/omithttp2.go
++++ b/src/net/http/omithttp2.go
+@@ -32,10 +32,6 @@ type http2Transport struct {
+ func (*http2Transport) RoundTrip(*Request) (*Response, error) { panic(noHTTP2) }
+ func (*http2Transport) CloseIdleConnections() {}
+
+-type http2erringRoundTripper struct{ err error }
+-
+-func (http2erringRoundTripper) RoundTrip(*Request) (*Response, error) { panic(noHTTP2) }
+-
+ type http2noDialH2RoundTripper struct{}
+
+ func (http2noDialH2RoundTripper) RoundTrip(*Request) (*Response, error) { panic(noHTTP2) }
+diff --git a/src/net/http/transport.go b/src/net/http/transport.go
+index 6e430b9885..88d15a5919 100644
+--- a/src/net/http/transport.go
++++ b/src/net/http/transport.go
+@@ -1531,6 +1531,10 @@ func (pconn *persistConn) addTLS(name string, trace *httptrace.ClientTrace) erro
+ return nil
+ }
+
++type erringRoundTripper interface {
++ RoundTripErr() error
++}
++
+ func (t *Transport) dialConn(ctx context.Context, cm connectMethod) (pconn *persistConn, err error) {
+ pconn = &persistConn{
+ t: t,
+@@ -1697,9 +1701,9 @@ func (t *Transport) dialConn(ctx context.Context, cm connectMethod) (pconn *pers
+ if s := pconn.tlsState; s != nil && s.NegotiatedProtocolIsMutual && s.NegotiatedProtocol != "" {
+ if next, ok := t.TLSNextProto[s.NegotiatedProtocol]; ok {
+ alt := next(cm.targetAddr, pconn.conn.(*tls.Conn))
+- if e, ok := alt.(http2erringRoundTripper); ok {
++ if e, ok := alt.(erringRoundTripper); ok {
+ // pconn.conn was closed by next (http2configureTransport.upgradeFn).
+- return nil, e.err
++ return nil, e.RoundTripErr()
+ }
+ return &persistConn{t: t, cacheKey: pconn.cacheKey, alt: alt}, nil
+ }
+--
+2.27.0
+
diff --git a/0029-release-branch.go1.15-build-set-GOPATH-consistently-.patch b/0029-release-branch.go1.15-build-set-GOPATH-consistently-.patch
new file mode 100644
index 0000000..a0a7d65
--- /dev/null
+++ b/0029-release-branch.go1.15-build-set-GOPATH-consistently-.patch
@@ -0,0 +1,105 @@
+From 6df5d3a581380a85183c591d1fd9063a5e8e4b23 Mon Sep 17 00:00:00 2001
+From: Russ Cox
+Date: Tue, 26 Jan 2021 21:14:43 -0500
+Subject: [PATCH 29/44] [release-branch.go1.15] build: set GOPATH consistently
+ in run.bash, run.bat, run.rc
+
+We used to clear GOPATH in all the build scripts.
+Clearing GOPATH is misleading at best, since you just end up
+with the default GOPATH (%USERPROFILE%\go on Windows).
+Unless that's your GOROOT, in which case you end up with a
+fatal error from the go command (#43938).
+
+run.bash changed to setting GOPATH=/dev/null, which has no
+clear analogue on Windows.
+
+run.rc still clears GOPATH.
+
+Change them all to set GOPATH to a non-existent directory
+/nonexist-gopath or c:\nonexist-gopath.
+
+For #45238.
+Fixes #45239.
+
+Change-Id: I51edd66d37ff6a891b0d0541d91ecba97fbbb03d
+Reviewed-on: https://go-review.googlesource.com/c/go/+/288818
+Trust: Russ Cox
+Trust: Jason A. Donenfeld
+Reviewed-by: Cherry Zhang
+Reviewed-by: Alex Brainman
+Reviewed-by: Jason A. Donenfeld
+(cherry picked from commit bb6efb96092cc8ae398c29e3b052a0051c746f88)
+Reviewed-on: https://go-review.googlesource.com/c/go/+/304773
+Run-TryBot: Dmitri Shuralyov
+TryBot-Result: Go Bot
+Reviewed-by: Alexander Rakoczy
+Reviewed-by: Carlos Amedee
+Trust: Carlos Amedee
+
+Conflict:NA
+Reference:https://github.com/golang/go/commit/6df5d3a581380a85183c591d1fd9063a5e8e4b23
+
+---
+ src/run.bash | 10 +---------
+ src/run.bat | 4 +---
+ src/run.rc | 9 ++++-----
+ 3 files changed, 6 insertions(+), 17 deletions(-)
+
+diff --git a/src/run.bash b/src/run.bash
+index 706b4b60ee..2123c509f8 100755
+--- a/src/run.bash
++++ b/src/run.bash
+@@ -23,15 +23,7 @@ fi
+
+ eval $(../bin/go env)
+ export GOROOT # The api test requires GOROOT to be set, so set it to match ../bin/go.
+-
+-# We disallow local import for non-local packages, if $GOROOT happens
+-# to be under $GOPATH, then some tests below will fail. $GOPATH needs
+-# to be set to a non-empty string, else Go will set a default value
+-# that may also conflict with $GOROOT. The $GOPATH value doesn't need
+-# to point to an actual directory, it just needs to pass the semantic
+-# checks performed by Go. Use $GOROOT to define $GOPATH so that we
+-# don't blunder into a user-defined symbolic link.
+-export GOPATH=/dev/null
++export GOPATH=/nonexist-gopath
+
+ unset CDPATH # in case user has it set
+ export GOBIN=$GOROOT/bin # Issue 14340
+diff --git a/src/run.bat b/src/run.bat
+index c299671c13..edcaf52659 100644
+--- a/src/run.bat
++++ b/src/run.bat
+@@ -18,9 +18,7 @@ setlocal
+
+ set GOBUILDFAIL=0
+
+-:: we disallow local import for non-local packages, if %GOROOT% happens
+-:: to be under %GOPATH%, then some tests below will fail
+-set GOPATH=
++set GOPATH=c:\nonexist-gopath
+ :: Issue 14340: ignore GOBIN during all.bat.
+ set GOBIN=
+ set GOFLAGS=
+diff --git a/src/run.rc b/src/run.rc
+index ab7abfa991..a7b4801207 100755
+--- a/src/run.rc
++++ b/src/run.rc
+@@ -12,10 +12,9 @@ if(! test -f ../bin/go){
+
+ eval `{../bin/go env}
+
+-GOPATH = () # we disallow local import for non-local packages, if $GOROOT happens
+- # to be under $GOPATH, then some tests below will fail
+-GOBIN = () # Issue 14340
+-GOFLAGS = ()
+-GO111MODULE = ()
++GOPATH=/nonexist-gopath
++GOBIN=() # Issue 14340
++GOFLAGS=()
++GO111MODULE=()
+
+ exec ../bin/go tool dist test -rebuild $*
+--
+2.27.0
+
diff --git a/0030-release-branch.go1.15-database-sql-fix-tx-stmt-deadl.patch b/0030-release-branch.go1.15-database-sql-fix-tx-stmt-deadl.patch
new file mode 100644
index 0000000..4d1c4ea
--- /dev/null
+++ b/0030-release-branch.go1.15-database-sql-fix-tx-stmt-deadl.patch
@@ -0,0 +1,134 @@
+From c77418f4cac41c42566ca90921a1f928995cfba2 Mon Sep 17 00:00:00 2001
+From: Emmanuel T Odeke
+Date: Mon, 18 Jan 2021 16:18:11 -0800
+Subject: [PATCH 30/44] [release-branch.go1.15] database/sql: fix tx stmt
+ deadlock when rollback
+
+Tx acquires tx.closemu W-lock and then acquires stmt.closemu.W-lock
+to fully close the transaction and associated prepared statement.
+Stmt query and execution run in reverse ways - acquires
+stmt.closemu.R-lock and then acquires tx.closemu.R-lock to grab tx
+connection, which may cause deadlock.
+
+Prevent the lock is held around tx.closePrepared to ensure no
+deadlock happens.
+
+Includes a test fix from CL 266097.
+Fixes #42884
+Updates #40985
+Updates #42259
+
+Change-Id: Id52737660ada3cebdfff6efc23366cdc3224b8e8
+Reviewed-on: https://go-review.googlesource.com/c/go/+/250178
+Run-TryBot: Emmanuel Odeke
+TryBot-Result: Go Bot
+Reviewed-by: Daniel Theophanes
+Trust: Emmanuel Odeke
+(cherry picked from commit d4c1ad882973e407ff85b977f4ce5b9435451190)
+Reviewed-on: https://go-review.googlesource.com/c/go/+/284513
+Reviewed-by: Dmitri Shuralyov
+
+Conflict:NA
+Reference:https://github.com/golang/go/commit/c77418f4cac41c42566ca90921a1f928995cfba2
+
+---
+ src/database/sql/sql.go | 14 +++++++-------
+ src/database/sql/sql_test.go | 28 ++++++++++++++++++++++++++++
+ 2 files changed, 35 insertions(+), 7 deletions(-)
+
+diff --git a/src/database/sql/sql.go b/src/database/sql/sql.go
+index b3d0653f5c..3d1367d28f 100644
+--- a/src/database/sql/sql.go
++++ b/src/database/sql/sql.go
+@@ -2080,10 +2080,10 @@ func (tx *Tx) isDone() bool {
+ // that has already been committed or rolled back.
+ var ErrTxDone = errors.New("sql: transaction has already been committed or rolled back")
+
+-// closeLocked returns the connection to the pool and
++// close returns the connection to the pool and
+ // must only be called by Tx.rollback or Tx.Commit while
+-// closemu is Locked and tx already canceled.
+-func (tx *Tx) closeLocked(err error) {
++// tx is already canceled and won't be executed concurrently.
++func (tx *Tx) close(err error) {
+ tx.releaseConn(err)
+ tx.dc = nil
+ tx.txi = nil
+@@ -2157,7 +2157,7 @@ func (tx *Tx) Commit() error {
+ // to ensure no other connection has an active query.
+ tx.cancel()
+ tx.closemu.Lock()
+- defer tx.closemu.Unlock()
++ tx.closemu.Unlock()
+
+ var err error
+ withLock(tx.dc, func() {
+@@ -2166,7 +2166,7 @@ func (tx *Tx) Commit() error {
+ if err != driver.ErrBadConn {
+ tx.closePrepared()
+ }
+- tx.closeLocked(err)
++ tx.close(err)
+ return err
+ }
+
+@@ -2189,7 +2189,7 @@ func (tx *Tx) rollback(discardConn bool) error {
+ // to ensure no other connection has an active query.
+ tx.cancel()
+ tx.closemu.Lock()
+- defer tx.closemu.Unlock()
++ tx.closemu.Unlock()
+
+ var err error
+ withLock(tx.dc, func() {
+@@ -2201,7 +2201,7 @@ func (tx *Tx) rollback(discardConn bool) error {
+ if discardConn {
+ err = driver.ErrBadConn
+ }
+- tx.closeLocked(err)
++ tx.close(err)
+ return err
+ }
+
+diff --git a/src/database/sql/sql_test.go b/src/database/sql/sql_test.go
+index 5727f0d8aa..d7d4642608 100644
+--- a/src/database/sql/sql_test.go
++++ b/src/database/sql/sql_test.go
+@@ -2810,6 +2810,34 @@ func TestTxCannotCommitAfterRollback(t *testing.T) {
+ }
+ }
+
++// Issue 40985 transaction statement deadlock while context cancel.
++func TestTxStmtDeadlock(t *testing.T) {
++ db := newTestDB(t, "people")
++ defer closeDB(t, db)
++
++ ctx, cancel := context.WithTimeout(context.Background(), 5*time.Millisecond)
++ defer cancel()
++ tx, err := db.BeginTx(ctx, nil)
++ if err != nil {
++ t.Fatal(err)
++ }
++
++ stmt, err := tx.Prepare("SELECT|people|name,age|age=?")
++ if err != nil {
++ t.Fatal(err)
++ }
++ // Run number of stmt queries to reproduce deadlock from context cancel
++ for i := 0; i < 1e3; i++ {
++ // Encounter any close related errors (e.g.. ErrTxDone, stmt is closed)
++ // is expected due to context cancel.
++ _, err = stmt.Query(1)
++ if err != nil {
++ break
++ }
++ }
++ _ = tx.Rollback()
++}
++
+ // Issue32530 encounters an issue where a connection may
+ // expire right after it comes out of a used connection pool
+ // even when a new connection is requested.
+--
+2.27.0
+
diff --git a/0031-release-branch.go1.15-cmd-compile-disable-shortcircu.patch b/0031-release-branch.go1.15-cmd-compile-disable-shortcircu.patch
new file mode 100644
index 0000000..fda0c96
--- /dev/null
+++ b/0031-release-branch.go1.15-cmd-compile-disable-shortcircu.patch
@@ -0,0 +1,107 @@
+From f17b659d0a9a43235f67c155b08023124b3fc35b Mon Sep 17 00:00:00 2001
+From: Keith Randall
+Date: Tue, 23 Mar 2021 14:48:47 -0700
+Subject: [PATCH 31/44] [release-branch.go1.15] cmd/compile: disable
+ shortcircuit optimization for intertwined phi values
+
+We need to be careful that when doing value graph surgery, we not
+re-substitute a value that has already been substituted. That can lead
+to confusing a previous iteration's value with the current iteration's
+value.
+
+The simple fix in this CL just aborts the optimization if it detects
+intertwined phis (a phi which is the argument to another phi). It
+might be possible to keep the optimization with a more complicated
+CL, but:
+ 1) This CL is clearly safe to backport.
+ 2) There were no instances of this abort triggering in
+ all.bash, prior to the test introduced in this CL.
+
+Fixes #45187
+
+Change-Id: I2411dca03948653c053291f6829a76bec0c32330
+Reviewed-on: https://go-review.googlesource.com/c/go/+/304251
+Trust: Keith Randall
+Trust: Josh Bleecher Snyder
+Run-TryBot: Keith Randall
+TryBot-Result: Go Bot
+Reviewed-by: Josh Bleecher Snyder
+(cherry picked from commit 771c57e68ed5ef2bbb0eafc0d48419f59d143932)
+Reviewed-on: https://go-review.googlesource.com/c/go/+/304529
+
+Conflict:NA
+Reference:https://github.com/golang/go/commit/f17b659d0a9a43235f67c155b08023124b3fc35b
+
+---
+ src/cmd/compile/internal/ssa/shortcircuit.go | 18 ++++++++++++
+ test/fixedbugs/issue45175.go | 29 ++++++++++++++++++++
+ 2 files changed, 47 insertions(+)
+ create mode 100644 test/fixedbugs/issue45175.go
+
+diff --git a/src/cmd/compile/internal/ssa/shortcircuit.go b/src/cmd/compile/internal/ssa/shortcircuit.go
+index c5df457c4e..9cf29fe413 100644
+--- a/src/cmd/compile/internal/ssa/shortcircuit.go
++++ b/src/cmd/compile/internal/ssa/shortcircuit.go
+@@ -138,6 +138,24 @@ func shortcircuitBlock(b *Block) bool {
+ if len(b.Values) != nval+nOtherPhi {
+ return false
+ }
++ if nOtherPhi > 0 {
++ // Check for any phi which is the argument of another phi.
++ // These cases are tricky, as substitutions done by replaceUses
++ // are no longer trivial to do in any ordering. See issue 45175.
++ m := make(map[*Value]bool, 1+nOtherPhi)
++ for _, v := range b.Values {
++ if v.Op == OpPhi {
++ m[v] = true
++ }
++ }
++ for v := range m {
++ for _, a := range v.Args {
++ if a != v && m[a] {
++ return false
++ }
++ }
++ }
++ }
+
+ // Locate index of first const phi arg.
+ cidx := -1
+diff --git a/test/fixedbugs/issue45175.go b/test/fixedbugs/issue45175.go
+new file mode 100644
+index 0000000000..02dfe8a0a9
+--- /dev/null
++++ b/test/fixedbugs/issue45175.go
+@@ -0,0 +1,29 @@
++// run
++
++// 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
++
++//go:noinline
++func f(c bool) int {
++ b := true
++ x := 0
++ y := 1
++ for b {
++ b = false
++ y = x
++ x = 2
++ if c {
++ return 3
++ }
++ }
++ return y
++}
++
++func main() {
++ if got := f(false); got != 0 {
++ panic(got)
++ }
++}
+--
+2.27.0
+
diff --git a/0032-release-branch.go1.15-runtime-non-strict-InlTreeInde.patch b/0032-release-branch.go1.15-runtime-non-strict-InlTreeInde.patch
new file mode 100644
index 0000000..58ee869
--- /dev/null
+++ b/0032-release-branch.go1.15-runtime-non-strict-InlTreeInde.patch
@@ -0,0 +1,157 @@
+From a07f9d2f82598d2f5cc0df0e813a6a2309cb96e6 Mon Sep 17 00:00:00 2001
+From: Michael Pratt
+Date: Thu, 11 Mar 2021 12:28:45 -0500
+Subject: [PATCH 32/44] [release-branch.go1.15] runtime: non-strict
+ InlTreeIndex lookup in Frames.Next
+
+When using cgo, some of the frames can be provided by cgoTraceback, a
+cgo-provided function to generate C tracebacks. Unlike Go tracebacks,
+cgoTraceback has no particular guarantees that it produces valid
+tracebacks.
+
+If one of the (invalid) frames happens to put the PC in the alignment
+region at the end of a function (filled with int 3's on amd64), then
+Frames.Next will find a valid funcInfo for the PC, but pcdatavalue will
+panic because PCDATA doesn't cover this PC.
+
+Tolerate this case by doing a non-strict PCDATA lookup. We'll still show
+a bogus frame, but at least avoid throwing.
+
+For #44971
+Fixes #45302
+
+Change-Id: I9eed728470d6f264179a7615bd19845c941db78c
+Reviewed-on: https://go-review.googlesource.com/c/go/+/301369
+Trust: Michael Pratt
+Run-TryBot: Michael Pratt
+TryBot-Result: Go Bot
+Reviewed-by: Cherry Zhang
+(cherry picked from commit e4a4161f1f3157550846e1b6bd4fe83aae15778e)
+Reviewed-on: https://go-review.googlesource.com/c/go/+/305890
+
+Conflict:NA
+Reference:https://github.com/golang/go/commit/a07f9d2f82598d2f5cc0df0e813a6a2309cb96e6
+
+---
+ src/runtime/symtab.go | 4 +-
+ src/runtime/symtab_test.go | 85 ++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 88 insertions(+), 1 deletion(-)
+
+diff --git a/src/runtime/symtab.go b/src/runtime/symtab.go
+index 1e86662adc..c77d513e74 100644
+--- a/src/runtime/symtab.go
++++ b/src/runtime/symtab.go
+@@ -102,7 +102,9 @@ func (ci *Frames) Next() (frame Frame, more bool) {
+ name := funcname(funcInfo)
+ if inldata := funcdata(funcInfo, _FUNCDATA_InlTree); inldata != nil {
+ inltree := (*[1 << 20]inlinedCall)(inldata)
+- ix := pcdatavalue(funcInfo, _PCDATA_InlTreeIndex, pc, nil)
++ // Non-strict as cgoTraceback may have added bogus PCs
++ // with a valid funcInfo but invalid PCDATA.
++ ix := pcdatavalue1(funcInfo, _PCDATA_InlTreeIndex, pc, nil, false)
+ if ix >= 0 {
+ // Note: entry is not modified. It always refers to a real frame, not an inlined one.
+ f = nil
+diff --git a/src/runtime/symtab_test.go b/src/runtime/symtab_test.go
+index 01e5002659..ffa07c7f3a 100644
+--- a/src/runtime/symtab_test.go
++++ b/src/runtime/symtab_test.go
+@@ -8,6 +8,7 @@ import (
+ "runtime"
+ "strings"
+ "testing"
++ "unsafe"
+ )
+
+ func TestCaller(t *testing.T) {
+@@ -165,3 +166,87 @@ func TestNilName(t *testing.T) {
+ t.Errorf("Name() = %q, want %q", got, "")
+ }
+ }
++
++var dummy int
++
++func inlined() {
++ // Side effect to prevent elimination of this entire function.
++ dummy = 42
++}
++
++// A function with an InlTree. Returns a PC within the function body.
++//
++// No inline to ensure this complete function appears in output.
++//
++//go:noinline
++func tracebackFunc(t *testing.T) uintptr {
++ // This body must be more complex than a single call to inlined to get
++ // an inline tree.
++ inlined()
++ inlined()
++
++ // Acquire a PC in this function.
++ pc, _, _, ok := runtime.Caller(0)
++ if !ok {
++ t.Fatalf("Caller(0) got ok false, want true")
++ }
++
++ return pc
++}
++
++// Test that CallersFrames handles PCs in the alignment region between
++// functions (int 3 on amd64) without crashing.
++//
++// Go will never generate a stack trace containing such an address, as it is
++// not a valid call site. However, the cgo traceback function passed to
++// runtime.SetCgoTraceback may not be completely accurate and may incorrect
++// provide PCs in Go code or the alignement region between functions.
++//
++// Go obviously doesn't easily expose the problematic PCs to running programs,
++// so this test is a bit fragile. Some details:
++//
++// * tracebackFunc is our target function. We want to get a PC in the
++// alignment region following this function. This function also has other
++// functions inlined into it to ensure it has an InlTree (this was the source
++// of the bug in issue 44971).
++//
++// * We acquire a PC in tracebackFunc, walking forwards until FuncForPC says
++// we're in a new function. The last PC of the function according to FuncForPC
++// should be in the alignment region (assuming the function isn't already
++// perfectly aligned).
++//
++// This is a regression test for issue 44971.
++func TestFunctionAlignmentTraceback(t *testing.T) {
++ pc := tracebackFunc(t)
++
++ // Double-check we got the right PC.
++ f := runtime.FuncForPC(pc)
++ if !strings.HasSuffix(f.Name(), "tracebackFunc") {
++ t.Fatalf("Caller(0) = %+v, want tracebackFunc", f)
++ }
++
++ // Iterate forward until we find a different function. Back up one
++ // instruction is (hopefully) an alignment instruction.
++ for runtime.FuncForPC(pc) == f {
++ pc++
++ }
++ pc--
++
++ // Is this an alignment region filler instruction? We only check this
++ // on amd64 for simplicity. If this function has no filler, then we may
++ // get a false negative, but will never get a false positive.
++ if runtime.GOARCH == "amd64" {
++ code := *(*uint8)(unsafe.Pointer(pc))
++ if code != 0xcc { // INT $3
++ t.Errorf("PC %v code got %#x want 0xcc", pc, code)
++ }
++ }
++
++ // Finally ensure that Frames.Next doesn't crash when processing this
++ // PC.
++ frames := runtime.CallersFrames([]uintptr{pc})
++ frame, _ := frames.Next()
++ if frame.Func != f {
++ t.Errorf("frames.Next() got %+v want %+v", frame.Func, f)
++ }
++}
+--
+2.27.0
+
diff --git a/0033-release-branch.go1.15-cmd-cgo-avoid-exporting-all-sy.patch b/0033-release-branch.go1.15-cmd-cgo-avoid-exporting-all-sy.patch
new file mode 100644
index 0000000..39bc904
--- /dev/null
+++ b/0033-release-branch.go1.15-cmd-cgo-avoid-exporting-all-sy.patch
@@ -0,0 +1,172 @@
+From 5055314a5749664ab66a24beed8158552e276959 Mon Sep 17 00:00:00 2001
+From: Quim Muntal
+Date: Thu, 15 Oct 2020 23:12:49 +0200
+Subject: [PATCH 33/44] [release-branch.go1.15] cmd/cgo: avoid exporting all
+ symbols on windows buildmode=c-shared
+
+Disable default symbol auto-export behaviour by marking exported
+function with the __declspec(dllexport) attribute. Old behaviour can
+still be used by setting -extldflags=-Wl,--export-all-symbols.
+
+See https://sourceware.org/binutils/docs/ld/WIN32.html for more info.
+
+This change cuts 50kb of a "hello world" dll.
+
+Updates #6853.
+Updates #30674.
+Fixes #43591.
+
+Change-Id: I9c7fb09c677cc760f24d0f7d199740ae73981413
+Reviewed-on: https://go-review.googlesource.com/c/go/+/262797
+Run-TryBot: Ian Lance Taylor
+TryBot-Result: Go Bot
+Reviewed-by: Ian Lance Taylor
+Reviewed-by: Alex Brainman
+Trust: Alex Brainman
+Reviewed-on: https://go-review.googlesource.com/c/go/+/300693
+Trust: Dmitri Shuralyov
+Run-TryBot: Dmitri Shuralyov
+Reviewed-by: David Chase
+
+Conflict:NA
+Reference:https://github.com/golang/go/commit/5055314a5749664ab66a24beed8158552e276959
+
+---
+ misc/cgo/testcshared/cshared_test.go | 96 ++++++++++++++++++++++++++++
+ src/cmd/cgo/out.go | 6 +-
+ 2 files changed, 101 insertions(+), 1 deletion(-)
+
+diff --git a/misc/cgo/testcshared/cshared_test.go b/misc/cgo/testcshared/cshared_test.go
+index bd4d341820..d717b4dfb3 100644
+--- a/misc/cgo/testcshared/cshared_test.go
++++ b/misc/cgo/testcshared/cshared_test.go
+@@ -7,6 +7,8 @@ package cshared_test
+ import (
+ "bytes"
+ "debug/elf"
++ "debug/pe"
++ "encoding/binary"
+ "flag"
+ "fmt"
+ "io/ioutil"
+@@ -355,6 +357,100 @@ func TestExportedSymbols(t *testing.T) {
+ }
+ }
+
++func checkNumberOfExportedFunctionsWindows(t *testing.T, exportAllSymbols bool) {
++ const prog = `
++package main
++
++import "C"
++
++//export GoFunc
++func GoFunc() {
++ println(42)
++}
++
++//export GoFunc2
++func GoFunc2() {
++ println(24)
++}
++
++func main() {
++}
++`
++
++ tmpdir := t.TempDir()
++
++ srcfile := filepath.Join(tmpdir, "test.go")
++ objfile := filepath.Join(tmpdir, "test.dll")
++ if err := ioutil.WriteFile(srcfile, []byte(prog), 0666); err != nil {
++ t.Fatal(err)
++ }
++ argv := []string{"build", "-buildmode=c-shared"}
++ if exportAllSymbols {
++ argv = append(argv, "-ldflags", "-extldflags=-Wl,--export-all-symbols")
++ }
++ argv = append(argv, "-o", objfile, srcfile)
++ out, err := exec.Command("go", argv...).CombinedOutput()
++ if err != nil {
++ t.Fatalf("build failure: %s\n%s\n", err, string(out))
++ }
++
++ f, err := pe.Open(objfile)
++ if err != nil {
++ t.Fatalf("pe.Open failed: %v", err)
++ }
++ defer f.Close()
++ section := f.Section(".edata")
++ if section == nil {
++ t.Error(".edata section is not present")
++ }
++
++ // TODO: deduplicate this struct from cmd/link/internal/ld/pe.go
++ type IMAGE_EXPORT_DIRECTORY struct {
++ _ [2]uint32
++ _ [2]uint16
++ _ [2]uint32
++ NumberOfFunctions uint32
++ NumberOfNames uint32
++ _ [3]uint32
++ }
++ var e IMAGE_EXPORT_DIRECTORY
++ if err := binary.Read(section.Open(), binary.LittleEndian, &e); err != nil {
++ t.Fatalf("binary.Read failed: %v", err)
++ }
++
++ expectedNumber := uint32(2)
++
++ if exportAllSymbols {
++ if e.NumberOfFunctions <= expectedNumber {
++ t.Fatalf("missing exported functions: %v", e.NumberOfFunctions)
++ }
++ if e.NumberOfNames <= expectedNumber {
++ t.Fatalf("missing exported names: %v", e.NumberOfNames)
++ }
++ } else {
++ if e.NumberOfFunctions != expectedNumber {
++ t.Fatalf("too many exported functions: %v", e.NumberOfFunctions)
++ }
++ if e.NumberOfNames != expectedNumber {
++ t.Fatalf("too many exported names: %v", e.NumberOfNames)
++ }
++ }
++}
++
++func TestNumberOfExportedFunctions(t *testing.T) {
++ if GOOS != "windows" {
++ t.Skip("skipping windows only test")
++ }
++ t.Parallel()
++
++ t.Run("OnlyExported", func(t *testing.T) {
++ checkNumberOfExportedFunctionsWindows(t, false)
++ })
++ t.Run("All", func(t *testing.T) {
++ checkNumberOfExportedFunctionsWindows(t, true)
++ })
++}
++
+ // test1: shared library can be dynamically loaded and exported symbols are accessible.
+ func TestExportedSymbolsWithDynamicLoad(t *testing.T) {
+ t.Parallel()
+diff --git a/src/cmd/cgo/out.go b/src/cmd/cgo/out.go
+index b9043efbf7..ee1c563495 100644
+--- a/src/cmd/cgo/out.go
++++ b/src/cmd/cgo/out.go
+@@ -961,7 +961,11 @@ func (p *Package) writeExports(fgo2, fm, fgcc, fgcch io.Writer) {
+ }
+
+ // Build the wrapper function compiled by gcc.
+- s := fmt.Sprintf("%s %s(", gccResult, exp.ExpName)
++ gccExport := ""
++ if goos == "windows" {
++ gccExport = "__declspec(dllexport)"
++ }
++ s := fmt.Sprintf("%s %s %s(", gccExport, gccResult, exp.ExpName)
+ if fn.Recv != nil {
+ s += p.cgoType(fn.Recv.List[0].Type).C.String()
+ s += " recv"
+--
+2.27.0
+
diff --git a/0034-release-branch.go1.15-cmd-link-avoid-exporting-all-s.patch b/0034-release-branch.go1.15-cmd-link-avoid-exporting-all-s.patch
new file mode 100644
index 0000000..123220e
--- /dev/null
+++ b/0034-release-branch.go1.15-cmd-link-avoid-exporting-all-s.patch
@@ -0,0 +1,188 @@
+From 82f9c6cac1bcc6bc80f17d1415ac3f62c0afa6c5 Mon Sep 17 00:00:00 2001
+From: Quim Muntal
+Date: Thu, 22 Oct 2020 22:32:20 +0200
+Subject: [PATCH 34/44] [release-branch.go1.15] cmd/link: avoid exporting all
+ symbols on windows buildmode=pie
+
+Marking one functions with __declspec(dllexport) forces mingw to
+create .reloc section without having to export all symbols.
+
+See https://insights.sei.cmu.edu/cert/2018/08/when-aslr-is-not-really-aslr---the-case-of-incorrect-assumptions-and-bad-defaults.html for more info.
+
+This change cuts 73kb of a "hello world" pie binary.
+
+Updates #6853.
+Updates #40795.
+Fixes #43592.
+
+Change-Id: I3cc57c3b64f61187550bc8751dfa085f106c8475
+Reviewed-on: https://go-review.googlesource.com/c/go/+/264459
+Trust: Alex Brainman
+Run-TryBot: Alex Brainman
+TryBot-Result: Go Bot
+Reviewed-by: Alex Brainman
+Reviewed-by: Austin Clements
+Reviewed-on: https://go-review.googlesource.com/c/go/+/300692
+Trust: Dmitri Shuralyov
+Run-TryBot: Dmitri Shuralyov
+Reviewed-by: David Chase
+
+Conflict:NA
+Reference:https://github.com/golang/go/commit/82f9c6cac1bcc6bc80f17d1415ac3f62c0afa6c5
+
+---
+ misc/cgo/testcshared/cshared_test.go | 9 ++++----
+ src/cmd/go/go_test.go | 33 ++++++++++++++++++++++++++++
+ src/cmd/link/internal/ld/lib.go | 3 ---
+ src/runtime/cgo/gcc_windows_386.c | 1 +
+ src/runtime/cgo/gcc_windows_amd64.c | 1 +
+ src/runtime/cgo/libcgo_windows.h | 12 ++++++++++
+ 6 files changed, 52 insertions(+), 7 deletions(-)
+ create mode 100644 src/runtime/cgo/libcgo_windows.h
+
+diff --git a/misc/cgo/testcshared/cshared_test.go b/misc/cgo/testcshared/cshared_test.go
+index d717b4dfb3..dff2682e20 100644
+--- a/misc/cgo/testcshared/cshared_test.go
++++ b/misc/cgo/testcshared/cshared_test.go
+@@ -401,7 +401,7 @@ func main() {
+ defer f.Close()
+ section := f.Section(".edata")
+ if section == nil {
+- t.Error(".edata section is not present")
++ t.Fatalf(".edata section is not present")
+ }
+
+ // TODO: deduplicate this struct from cmd/link/internal/ld/pe.go
+@@ -418,7 +418,8 @@ func main() {
+ t.Fatalf("binary.Read failed: %v", err)
+ }
+
+- expectedNumber := uint32(2)
++ // Only the two exported functions and _cgo_dummy_export should be exported
++ expectedNumber := uint32(3)
+
+ if exportAllSymbols {
+ if e.NumberOfFunctions <= expectedNumber {
+@@ -429,10 +430,10 @@ func main() {
+ }
+ } else {
+ if e.NumberOfFunctions != expectedNumber {
+- t.Fatalf("too many exported functions: %v", e.NumberOfFunctions)
++ t.Fatalf("got %d exported functions; want %d", e.NumberOfFunctions, expectedNumber)
+ }
+ if e.NumberOfNames != expectedNumber {
+- t.Fatalf("too many exported names: %v", e.NumberOfNames)
++ t.Fatalf("got %d exported names; want %d", e.NumberOfNames, expectedNumber)
+ }
+ }
+ }
+diff --git a/src/cmd/go/go_test.go b/src/cmd/go/go_test.go
+index 021930a8a8..3f790cdeab 100644
+--- a/src/cmd/go/go_test.go
++++ b/src/cmd/go/go_test.go
+@@ -9,6 +9,7 @@ import (
+ "debug/elf"
+ "debug/macho"
+ "debug/pe"
++ "encoding/binary"
+ "flag"
+ "fmt"
+ "go/format"
+@@ -2166,6 +2167,38 @@ func testBuildmodePIE(t *testing.T, useCgo, setBuildmodeToPIE bool) {
+ if (dc & pe.IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE) == 0 {
+ t.Error("IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE flag is not set")
+ }
++ if useCgo {
++ // Test that only one symbol is exported (#40795).
++ // PIE binaries don´t require .edata section but unfortunately
++ // binutils doesn´t generate a .reloc section unless there is
++ // at least one symbol exported.
++ // See https://sourceware.org/bugzilla/show_bug.cgi?id=19011
++ section := f.Section(".edata")
++ if section == nil {
++ t.Fatalf(".edata section is not present")
++ }
++ // TODO: deduplicate this struct from cmd/link/internal/ld/pe.go
++ type IMAGE_EXPORT_DIRECTORY struct {
++ _ [2]uint32
++ _ [2]uint16
++ _ [2]uint32
++ NumberOfFunctions uint32
++ NumberOfNames uint32
++ _ [3]uint32
++ }
++ var e IMAGE_EXPORT_DIRECTORY
++ if err := binary.Read(section.Open(), binary.LittleEndian, &e); err != nil {
++ t.Fatalf("binary.Read failed: %v", err)
++ }
++
++ // Only _cgo_dummy_export should be exported
++ if e.NumberOfFunctions != 1 {
++ t.Fatalf("got %d exported functions; want 1", e.NumberOfFunctions)
++ }
++ if e.NumberOfNames != 1 {
++ t.Fatalf("got %d exported names; want 1", e.NumberOfNames)
++ }
++ }
+ default:
+ panic("unreachable")
+ }
+diff --git a/src/cmd/link/internal/ld/lib.go b/src/cmd/link/internal/ld/lib.go
+index fc89759997..d03fb6cf91 100644
+--- a/src/cmd/link/internal/ld/lib.go
++++ b/src/cmd/link/internal/ld/lib.go
+@@ -1423,9 +1423,6 @@ func (ctxt *Link) hostlink() {
+ if ctxt.Arch.PtrSize >= 8 {
+ argv = append(argv, "-Wl,--high-entropy-va")
+ }
+- // Work around binutils limitation that strips relocation table for dynamicbase.
+- // See https://sourceware.org/bugzilla/show_bug.cgi?id=19011
+- argv = append(argv, "-Wl,--export-all-symbols")
+ default:
+ // ELF.
+ if ctxt.UseRelro() {
+diff --git a/src/runtime/cgo/gcc_windows_386.c b/src/runtime/cgo/gcc_windows_386.c
+index 9184b91393..60cb011bf2 100644
+--- a/src/runtime/cgo/gcc_windows_386.c
++++ b/src/runtime/cgo/gcc_windows_386.c
+@@ -9,6 +9,7 @@
+ #include
+ #include
+ #include "libcgo.h"
++#include "libcgo_windows.h"
+
+ static void threadentry(void*);
+
+diff --git a/src/runtime/cgo/gcc_windows_amd64.c b/src/runtime/cgo/gcc_windows_amd64.c
+index 7192a24631..0f8c817f0e 100644
+--- a/src/runtime/cgo/gcc_windows_amd64.c
++++ b/src/runtime/cgo/gcc_windows_amd64.c
+@@ -9,6 +9,7 @@
+ #include
+ #include
+ #include "libcgo.h"
++#include "libcgo_windows.h"
+
+ static void threadentry(void*);
+
+diff --git a/src/runtime/cgo/libcgo_windows.h b/src/runtime/cgo/libcgo_windows.h
+new file mode 100644
+index 0000000000..0013f06bae
+--- /dev/null
++++ b/src/runtime/cgo/libcgo_windows.h
+@@ -0,0 +1,12 @@
++// Copyright 2020 The Go Authors. All rights reserved.
++// Use of this source code is governed by a BSD-style
++// license that can be found in the LICENSE file.
++
++// Ensure there's one symbol marked __declspec(dllexport).
++// If there are no exported symbols, the unfortunate behavior of
++// the binutils linker is to also strip the relocations table,
++// resulting in non-PIE binary. The other option is the
++// --export-all-symbols flag, but we don't need to export all symbols
++// and this may overflow the export table (#40795).
++// See https://sourceware.org/bugzilla/show_bug.cgi?id=19011
++__declspec(dllexport) int _cgo_dummy_export;
+--
+2.27.0
+
diff --git a/0035-release-branch.go1.15-cmd-cgo-remove-unnecessary-spa.patch b/0035-release-branch.go1.15-cmd-cgo-remove-unnecessary-spa.patch
new file mode 100644
index 0000000..8d3c8a5
--- /dev/null
+++ b/0035-release-branch.go1.15-cmd-cgo-remove-unnecessary-spa.patch
@@ -0,0 +1,60 @@
+From 1373d92a75f70c62d74f9e4714cd17811f75c48b Mon Sep 17 00:00:00 2001
+From: Quim Muntal
+Date: Thu, 14 Jan 2021 21:29:49 +0100
+Subject: [PATCH 35/44] [release-branch.go1.15] cmd/cgo: remove unnecessary
+ space in cgo export header
+
+The cgo header has an unnecessary space in the exported function
+definition on non-windows goos.
+
+This was introduced in go1.16 so it would be good to fix it before
+release.
+
+Example:
+
+// Current behavior, notice there is an unecessary space
+// between extern and void
+extern void Foo();
+
+// With this CL
+extern void Foo();
+
+Updates #43591.
+
+Change-Id: Ic2c21f8d806fe35a7be7183dbfe35ac605b6e4f6
+Reviewed-on: https://go-review.googlesource.com/c/go/+/283892
+Reviewed-by: Ian Lance Taylor
+Trust: Katie Hockman
+Reviewed-on: https://go-review.googlesource.com/c/go/+/300694
+Trust: Dmitri Shuralyov
+Trust: Emmanuel Odeke
+Run-TryBot: Dmitri Shuralyov
+TryBot-Result: Go Bot
+Reviewed-by: David Chase
+
+Conflict:NA
+Reference:https://github.com/golang/go/commit/1373d92a75f70c62d74f9e4714cd17811f75c48b
+
+---
+ src/cmd/cgo/out.go | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/src/cmd/cgo/out.go b/src/cmd/cgo/out.go
+index ee1c563495..be4f6ad2d5 100644
+--- a/src/cmd/cgo/out.go
++++ b/src/cmd/cgo/out.go
+@@ -963,9 +963,9 @@ func (p *Package) writeExports(fgo2, fm, fgcc, fgcch io.Writer) {
+ // Build the wrapper function compiled by gcc.
+ gccExport := ""
+ if goos == "windows" {
+- gccExport = "__declspec(dllexport)"
++ gccExport = "__declspec(dllexport) "
+ }
+- s := fmt.Sprintf("%s %s %s(", gccExport, gccResult, exp.ExpName)
++ s := fmt.Sprintf("%s%s %s(", gccExport, gccResult, exp.ExpName)
+ if fn.Recv != nil {
+ s += p.cgoType(fn.Recv.List[0].Type).C.String()
+ s += " recv"
+--
+2.27.0
+
diff --git a/0037-release-branch.go1.15-time-use-offset-and-isDST-when.patch b/0037-release-branch.go1.15-time-use-offset-and-isDST-when.patch
new file mode 100644
index 0000000..dc7e32c
--- /dev/null
+++ b/0037-release-branch.go1.15-time-use-offset-and-isDST-when.patch
@@ -0,0 +1,355 @@
+From 06c9756333bb506dcbf322be77af85b3162b6345 Mon Sep 17 00:00:00 2001
+From: Ian Lance Taylor
+Date: Mon, 5 Apr 2021 12:12:25 -0700
+Subject: [PATCH 37/44] [release-branch.go1.15] time: use offset and isDST when
+ caching zone from extend string
+
+If the current time is computed from extend string
+and the zone file contains multiple zones with the
+same name, the lookup by name might find incorrect
+zone.
+
+This happens for example with the slim Europe/Dublin
+time zone file in the embedded zip. This zone file
+has last transition in 1996 and rest is covered by
+extend string.
+tzset returns IST as the zone name to use, but there
+are two records with IST name. Lookup by name finds
+the wrong one. We need to check offset and isDST too.
+
+In case we can't find an existing zone, we allocate
+a new zone so that we use correct offset and isDST.
+
+I have renamed zone variable to zones as it shadowed
+the zone type that we need to allocate the cached zone.
+
+Backport note: this change also incorporates portions of
+CL 264077.
+
+For #45370
+Fixes #45384
+
+Change-Id: I43d416d009e20878261156c821a5784e2407ed1f
+Reviewed-on: https://go-review.googlesource.com/c/go/+/307212
+Trust: Ian Lance Taylor
+Run-TryBot: Ian Lance Taylor
+TryBot-Result: Go Bot
+Reviewed-by: Emmanuel Odeke
+
+Conflict:NA
+Reference:https://github.com/golang/go/commit/06c9756333bb506dcbf322be77af85b3162b6345
+
+---
+ src/time/zoneinfo.go | 27 ++++++++++++++----------
+ src/time/zoneinfo_read.go | 44 ++++++++++++++++++++++++---------------
+ src/time/zoneinfo_test.go | 37 +++++++++++++++++++++-----------
+ 3 files changed, 68 insertions(+), 40 deletions(-)
+
+diff --git a/src/time/zoneinfo.go b/src/time/zoneinfo.go
+index 6db9443474..57052338d0 100644
+--- a/src/time/zoneinfo.go
++++ b/src/time/zoneinfo.go
+@@ -178,7 +178,7 @@ func (l *Location) lookup(sec int64) (name string, offset int, start, end int64)
+ // If we're at the end of the known zone transitions,
+ // try the extend string.
+ if lo == len(tx)-1 && l.extend != "" {
+- if ename, eoffset, estart, eend, ok := tzset(l.extend, end, sec); ok {
++ if ename, eoffset, estart, eend, _, ok := tzset(l.extend, end, sec); ok {
+ return ename, eoffset, estart, eend
+ }
+ }
+@@ -244,7 +244,7 @@ func (l *Location) firstZoneUsed() bool {
+ // We call this a tzset string since in C the function tzset reads TZ.
+ // The return values are as for lookup, plus ok which reports whether the
+ // parse succeeded.
+-func tzset(s string, initEnd, sec int64) (name string, offset int, start, end int64, ok bool) {
++func tzset(s string, initEnd, sec int64) (name string, offset int, start, end int64, isDST, ok bool) {
+ var (
+ stdName, dstName string
+ stdOffset, dstOffset int
+@@ -255,7 +255,7 @@ func tzset(s string, initEnd, sec int64) (name string, offset int, start, end in
+ stdOffset, s, ok = tzsetOffset(s)
+ }
+ if !ok {
+- return "", 0, 0, 0, false
++ return "", 0, 0, 0, false, false
+ }
+
+ // The numbers in the tzset string are added to local time to get UTC,
+@@ -265,7 +265,7 @@ func tzset(s string, initEnd, sec int64) (name string, offset int, start, end in
+
+ if len(s) == 0 || s[0] == ',' {
+ // No daylight savings time.
+- return stdName, stdOffset, initEnd, omega, true
++ return stdName, stdOffset, initEnd, omega, false, true
+ }
+
+ dstName, s, ok = tzsetName(s)
+@@ -278,7 +278,7 @@ func tzset(s string, initEnd, sec int64) (name string, offset int, start, end in
+ }
+ }
+ if !ok {
+- return "", 0, 0, 0, false
++ return "", 0, 0, 0, false, false
+ }
+
+ if len(s) == 0 {
+@@ -287,19 +287,19 @@ func tzset(s string, initEnd, sec int64) (name string, offset int, start, end in
+ }
+ // The TZ definition does not mention ';' here but tzcode accepts it.
+ if s[0] != ',' && s[0] != ';' {
+- return "", 0, 0, 0, false
++ return "", 0, 0, 0, false, false
+ }
+ s = s[1:]
+
+ var startRule, endRule rule
+ startRule, s, ok = tzsetRule(s)
+ if !ok || len(s) == 0 || s[0] != ',' {
+- return "", 0, 0, 0, false
++ return "", 0, 0, 0, false, false
+ }
+ s = s[1:]
+ endRule, s, ok = tzsetRule(s)
+ if !ok || len(s) > 0 {
+- return "", 0, 0, 0, false
++ return "", 0, 0, 0, false, false
+ }
+
+ year, _, _, yday := absDate(uint64(sec+unixToInternal+internalToAbsolute), false)
+@@ -313,10 +313,15 @@ func tzset(s string, initEnd, sec int64) (name string, offset int, start, end in
+
+ startSec := int64(tzruleTime(year, startRule, stdOffset))
+ endSec := int64(tzruleTime(year, endRule, dstOffset))
++ dstIsDST, stdIsDST := true, false
++ // Note: this is a flipping of "DST" and "STD" while retaining the labels
++ // This happens in southern hemispheres. The labelling here thus is a little
++ // inconsistent with the goal.
+ if endSec < startSec {
+ startSec, endSec = endSec, startSec
+ stdName, dstName = dstName, stdName
+ stdOffset, dstOffset = dstOffset, stdOffset
++ stdIsDST, dstIsDST = dstIsDST, stdIsDST
+ }
+
+ // The start and end values that we return are accurate
+@@ -324,11 +329,11 @@ func tzset(s string, initEnd, sec int64) (name string, offset int, start, end in
+ // just the start and end of the year. That suffices for
+ // the only caller that cares, which is Date.
+ if ysec < startSec {
+- return stdName, stdOffset, abs, startSec + abs, true
++ return stdName, stdOffset, abs, startSec + abs, stdIsDST, true
+ } else if ysec >= endSec {
+- return stdName, stdOffset, endSec + abs, abs + 365*secondsPerDay, true
++ return stdName, stdOffset, endSec + abs, abs + 365*secondsPerDay, stdIsDST, true
+ } else {
+- return dstName, dstOffset, startSec + abs, endSec + abs, true
++ return dstName, dstOffset, startSec + abs, endSec + abs, dstIsDST, true
+ }
+ }
+
+diff --git a/src/time/zoneinfo_read.go b/src/time/zoneinfo_read.go
+index 22a60f3211..f7fe59c385 100644
+--- a/src/time/zoneinfo_read.go
++++ b/src/time/zoneinfo_read.go
+@@ -247,8 +247,8 @@ func LoadLocationFromTZData(name string, data []byte) (*Location, error) {
+ // This also avoids a panic later when we add and then use a fake transition (golang.org/issue/29437).
+ return nil, badData
+ }
+- zone := make([]zone, nzone)
+- for i := range zone {
++ zones := make([]zone, nzone)
++ for i := range zones {
+ var ok bool
+ var n uint32
+ if n, ok = zonedata.big4(); !ok {
+@@ -257,22 +257,22 @@ func LoadLocationFromTZData(name string, data []byte) (*Location, error) {
+ if uint32(int(n)) != n {
+ return nil, badData
+ }
+- zone[i].offset = int(int32(n))
++ zones[i].offset = int(int32(n))
+ var b byte
+ if b, ok = zonedata.byte(); !ok {
+ return nil, badData
+ }
+- zone[i].isDST = b != 0
++ zones[i].isDST = b != 0
+ if b, ok = zonedata.byte(); !ok || int(b) >= len(abbrev) {
+ return nil, badData
+ }
+- zone[i].name = byteString(abbrev[b:])
++ zones[i].name = byteString(abbrev[b:])
+ if runtime.GOOS == "aix" && len(name) > 8 && (name[:8] == "Etc/GMT+" || name[:8] == "Etc/GMT-") {
+ // There is a bug with AIX 7.2 TL 0 with files in Etc,
+ // GMT+1 will return GMT-1 instead of GMT+1 or -01.
+ if name != "Etc/GMT+0" {
+ // GMT+0 is OK
+- zone[i].name = name[4:]
++ zones[i].name = name[4:]
+ }
+ }
+ }
+@@ -295,7 +295,7 @@ func LoadLocationFromTZData(name string, data []byte) (*Location, error) {
+ }
+ }
+ tx[i].when = n
+- if int(txzones[i]) >= len(zone) {
++ if int(txzones[i]) >= len(zones) {
+ return nil, badData
+ }
+ tx[i].index = txzones[i]
+@@ -314,7 +314,7 @@ func LoadLocationFromTZData(name string, data []byte) (*Location, error) {
+ }
+
+ // Committed to succeed.
+- l := &Location{zone: zone, tx: tx, name: name, extend: extend}
++ l := &Location{zone: zones, tx: tx, name: name, extend: extend}
+
+ // Fill in the cache with information about right now,
+ // since that will be the most common lookup.
+@@ -323,26 +323,27 @@ func LoadLocationFromTZData(name string, data []byte) (*Location, error) {
+ if tx[i].when <= sec && (i+1 == len(tx) || sec < tx[i+1].when) {
+ l.cacheStart = tx[i].when
+ l.cacheEnd = omega
+- zoneIdx := tx[i].index
++ l.cacheZone = &l.zone[tx[i].index]
+ if i+1 < len(tx) {
+ l.cacheEnd = tx[i+1].when
+ } else if l.extend != "" {
+ // If we're at the end of the known zone transitions,
+ // try the extend string.
+- if name, _, estart, eend, ok := tzset(l.extend, l.cacheEnd, sec); ok {
++ if name, offset, estart, eend, isDST, ok := tzset(l.extend, l.cacheEnd, sec); ok {
+ l.cacheStart = estart
+ l.cacheEnd = eend
+- // Find the zone that is returned by tzset,
+- // the last transition is not always the correct zone.
+- for i, z := range l.zone {
+- if z.name == name {
+- zoneIdx = uint8(i)
+- break
++ // Find the zone that is returned by tzset to avoid allocation if possible.
++ if zoneIdx := findZone(l.zone, name, offset, isDST); zoneIdx != -1 {
++ l.cacheZone = &l.zone[zoneIdx]
++ } else {
++ l.cacheZone = &zone{
++ name: name,
++ offset: offset,
++ isDST: isDST,
+ }
+ }
+ }
+ }
+- l.cacheZone = &l.zone[zoneIdx]
+ break
+ }
+ }
+@@ -350,6 +351,15 @@ func LoadLocationFromTZData(name string, data []byte) (*Location, error) {
+ return l, nil
+ }
+
++func findZone(zones []zone, name string, offset int, isDST bool) int {
++ for i, z := range zones {
++ if z.name == name && z.offset == offset && z.isDST == isDST {
++ return i
++ }
++ }
++ return -1
++}
++
+ // loadTzinfoFromDirOrZip returns the contents of the file with the given name
+ // in dir. dir can either be an uncompressed zip file, or a directory.
+ func loadTzinfoFromDirOrZip(dir, name string) ([]byte, error) {
+diff --git a/src/time/zoneinfo_test.go b/src/time/zoneinfo_test.go
+index d043e1e9f1..7ba1229741 100644
+--- a/src/time/zoneinfo_test.go
++++ b/src/time/zoneinfo_test.go
+@@ -186,6 +186,7 @@ func TestMalformedTZData(t *testing.T) {
+ var slimTests = []struct {
+ zoneName string
+ tzData string
++ date func(*time.Location) time.Time
+ wantName string
+ wantOffset int
+ }{
+@@ -193,6 +194,7 @@ var slimTests = []struct {
+ // 2020b slim tzdata for Europe/Berlin.
+ zoneName: "Europe/Berlin",
+ tzData: "TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00<\x00\x00\x00\x04\x00\x00\x00\x12\xff\xff\xff\xffo\xa2a\xf8\xff\xff\xff\xff\x9b\f\x17`\xff\xff\xff\xff\x9b\xd5\xda\xf0\xff\xff\xff\xff\x9cٮ\x90\xff\xff\xff\xff\x9d\xa4\xb5\x90\xff\xff\xff\xff\x9e\xb9\x90\x90\xff\xff\xff\xff\x9f\x84\x97\x90\xff\xff\xff\xff\xc8\tq\x90\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xffϒ4\x10\xff\xff\xff\xffЂ%\x10\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xffѶ\x96\x00\xff\xff\xff\xff\xd2X\xbe\x80\xff\xff\xff\xffҡO\x10\xff\xff\xff\xff\xd3c\x1b\x90\xff\xff\xff\xff\xd4K#\x90\xff\xff\xff\xff\xd59\xd1 \xff\xff\xff\xff\xd5g\xe7\x90\xff\xff\xff\xffըs\x00\xff\xff\xff\xff\xd6)\xb4\x10\xff\xff\xff\xff\xd7,\x1a\x10\xff\xff\xff\xff\xd8\t\x96\x10\xff\xff\xff\xff\xd9\x02\xc1\x90\xff\xff\xff\xff\xd9\xe9x\x10\x00\x00\x00\x00\x13MD\x10\x00\x00\x00\x00\x143\xfa\x90\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13ܐ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#3<-02>,M3.5.0/-2,M10.5.0/-1\n",
++ date: func(loc *time.Location) time.Time { return time.Date(2020, time.October, 29, 15, 30, 0, 0, loc) },
+ wantName: "-03",
+ wantOffset: -10800,
+ },
+@@ -207,9 +210,18 @@ var slimTests = []struct {
+ // 2021a slim tzdata for Asia/Gaza.
+ zoneName: "Asia/Gaza",
+ tzData: "TZif3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00s\x00\x00\x00\x05\x00\x00\x00\x15\xff\xff\xff\xff}\xbdJ\xb0\xff\xff\xff\xff\xc8Y\xcf\x00\xff\xff\xff\xff\xc8\xfa\xa6\x00\xff\xff\xff\xff\xc98\x9c\x80\xff\xff\xff\xff\xcc\xe5\xeb\x80\xff\xff\xff\xffͬ\xfe\x00\xff\xff\xff\xff\xce\xc7\x1f\x00\xff\xff\xff\xffϏ\x83\x00\xff\xff\xff\xffЩ\xa4\x00\xff\xff\xff\xffф}\x00\xff\xff\xff\xffҊ׀\xff\xff\xff\xff\xd3e\xb0\x80\xff\xff\xff\xff\xd4l\v\x00\xff\xff\xff\xff\xe86c`\xff\xff\xff\xff\xe8\xf4-P\xff\xff\xff\xff\xea\v\xb9`\xff\xff\xff\xff\xea\xd5`\xd0\xff\xff\xff\xff\xeb\xec\xfa\xf0\xff\xff\xff\xff\xec\xb5m\x00\xff\xff\xff\xff\xed\xcf\u007f\xf0\xff\xff\xff\xff\xee\x97\xf2\x00\xff\xff\xff\xffﰳp\xff\xff\xff\xff\xf0y%\x80\xff\xff\xff\xff\xf1\x91\xe6\xf0\xff\xff\xff\xff\xf2ZY\x00\xff\xff\xff\xff\xf3s\x1ap\xff\xff\xff\xff\xf4;\x8c\x80\xff\xff\xff\xff\xf5U\x9fp\xff\xff\xff\xff\xf6\x1e\x11\x80\xff\xff\xff\xff\xf76\xd2\xf0\xff\xff\xff\xff\xf7\xffE\x00\xff\xff\xff\xff\xf9\x18\x06p\xff\xff\xff\xff\xf9\xe1\xca\x00\xff\xff\xff\xff\xfa\xf99\xf0\xff\xff\xff\xff\xfb'BP\x00\x00\x00\x00\b|\x8b\xe0\x00\x00\x00\x00\b\xfd\xb0\xd0\x00\x00\x00\x00\t\xf6\xea`\x00\x00\x00\x00\n\xa63\xd0\x00\x00\x00\x00\x13\xe9\xfc`\x00\x00\x00\x00\x14![`\x00\x00\x00\x00\x1a\xfa\xc6`\x00\x00\x00\x00\x1b\x8en`\x00\x00\x00\x00\x1c\xbe\xf8\xe0\x00\x00\x00\x00\x1dw|\xd0\x00\x00\x00\x00\x1e\xcc\xff`\x00\x00\x00\x00\x1f`\x99P\x00\x00\x00\x00 \x82\xb1`\x00\x00\x00\x00!I\xb5\xd0\x00\x00\x00\x00\"^\x9e\xe0\x00\x00\x00\x00# ]P\x00\x00\x00\x00$Z0`\x00\x00\x00\x00%\x00?P\x00\x00\x00\x00&\v\xed\xe0\x00\x00\x00\x00&\xd6\xe6\xd0\x00\x00\x00\x00'\xeb\xcf\xe0\x00\x00\x00\x00(\xc0\x03P\x00\x00\x00\x00)\xd4\xec`\x00\x00\x00\x00*\xa9\x1f\xd0\x00\x00\x00\x00+\xbbe\xe0\x00\x00\x00\x00,\x89\x01\xd0\x00\x00\x00\x00-\x9bG\xe0\x00\x00\x00\x00._\xa9P\x00\x00\x00\x00/{)\xe0\x00\x00\x00\x000H\xc5\xd0\x00\x00\x00\x000\xe7\a\xe0\x00\x00\x00\x001dF`\x00\x00\x00\x002A\xc2`\x00\x00\x00\x003D(`\x00\x00\x00\x004!\xa4`\x00\x00\x00\x005$\n`\x00\x00\x00\x006\x01\x86`\x00\x00\x00\x007\x16a`\x00\x00\x00\x008\x06DP\x00\x00\x00\x008\xff}\xe0\x00\x00\x00\x009\xef`\xd0\x00\x00\x00\x00:\xdf_\xe0\x00\x00\x00\x00;\xcfB\xd0\x00\x00\x00\x00<\xbfA\xe0\x00\x00\x00\x00=\xaf$\xd0\x00\x00\x00\x00>\x9f#\xe0\x00\x00\x00\x00?\x8f\x06\xd0\x00\x00\x00\x00@\u007f\x05\xe0\x00\x00\x00\x00A\\\x81\xe0\x00\x00\x00\x00B^\xe7\xe0\x00\x00\x00\x00CA\xb7\xf0\x00\x00\x00\x00D-\xa6`\x00\x00\x00\x00E\x12\xfdP\x00\x00\x00\x00F\x0e\xd9\xe0\x00\x00\x00\x00F\xe8op\x00\x00\x00\x00G\xec\x18\xe0\x00\x00\x00\x00H\xb7\x11\xd0\x00\x00\x00\x00I\xcb\xfa\xe0\x00\x00\x00\x00J\xa0<`\x00\x00\x00\x00K\xad.\x9c\x00\x00\x00\x00La\xbd\xd0\x00\x00\x00\x00M\x94\xf9\x9c\x00\x00\x00\x00N5\xc2P\x00\x00\x00\x00Ot\xdb`\x00\x00\x00\x00P[\x91\xe0\x00\x00\x00\x00QT\xbd`\x00\x00\x00\x00RD\xa0P\x00\x00\x00\x00S4\x9f`\x00\x00\x00\x00TIlP\x00\x00\x00\x00U\x15\xd2\xe0\x00\x00\x00\x00V)\\`\x00\x00\x00\x00V\xf5\xc2\xf0\x00\x00\x00\x00X\x13\xca`\x00\x00\x00\x00Xդ\xf0\x00\x00\x00\x00Y\xf3\xac`\x00\x00\x00\x00Z\xb5\x86\xf0\x00\x00\x00\x00[ӎ`\x00\x00\x00\x00\\\x9dC\xe0\x00\x00\x00\x00]\xb3bP\x00\x00\x00\x00^~w`\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x00\x00 P\x00\x00\x00\x00*0\x01\x04\x00\x00\x1c \x00\t\x00\x00*0\x01\r\x00\x00\x1c \x00\x11LMT\x00EEST\x00EET\x00IDT\x00IST\x00\nEET-2EEST,M3.4.4/48,M10.4.4/49\n",
++ date: func(loc *time.Location) time.Time { return time.Date(2020, time.October, 29, 15, 30, 0, 0, loc) },
+ wantName: "EET",
+ wantOffset: 7200,
+ },
++ {
++ // 2021a slim tzdata for Europe/Dublin.
++ zoneName: "Europe/Dublin",
++ tzData: "TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x91\x00\x00\x00\x08\x00\x00\x00\x14\xff\xff\xff\xffW\xd1\n\xdc\xff\xff\xff\xff\x9b&\xb3\x91\xff\xff\xff\xff\x9b\xd6\x0b\x11\xff\xff\xff\xff\x9c\xcf0\xa0\xff\xff\xff\xff\x9d\xa4\xc3\xa0\xff\xff\xff\xff\x9e\x9c\x9d\xa0\xff\xff\xff\xff\x9f\x97\x1a\xa0\xff\xff\xff\xff\xa0\x85\xba\x20\xff\xff\xff\xff\xa1v\xfc\xa0\xff\xff\xff\xff\xa2e\x9c\x20\xff\xff\xff\xff\xa3{\xc8\xa0\xff\xff\xff\xff\xa4N\xb8\xa0\xff\xff\xff\xff\xa5?\xfb\x20\xff\xff\xff\xff\xa6%`\x20\xff\xff\xff\xff\xa7'\xc6\x20\xff\xff\xff\xff\xa8*,\x20\xff\xff\xff\xff\xa8\xeb\xf8\xa0\xff\xff\xff\xff\xaa\x00\xd3\xa0\xff\xff\xff\xff\xaa\xd5\x15\x20\xff\xff\xff\xff\xab\xe9\xf0\x20\xff\xff\xff\xff\xac\xc7l\x20\xff\xff\xff\xff\xad\xc9\xd2\x20\xff\xff\xff\xff\xae\xa7N\x20\xff\xff\xff\xff\xaf\xa0y\xa0\xff\xff\xff\xff\xb0\x870\x20\xff\xff\xff\xff\xb1\x92\xd0\xa0\xff\xff\xff\xff\xb2pL\xa0\xff\xff\xff\xff\xb3r\xb2\xa0\xff\xff\xff\xff\xb4P.\xa0\xff\xff\xff\xff\xb5IZ\x20\xff\xff\xff\xff\xb60\x10\xa0\xff\xff\xff\xff\xb72v\xa0\xff\xff\xff\xff\xb8\x0f\xf2\xa0\xff\xff\xff\xff\xb9\x12X\xa0\xff\xff\xff\xff\xb9\xef\xd4\xa0\xff\xff\xff\xff\xba\xe9\x00\x20\xff\xff\xff\xff\xbb\xd8\xf1\x20\xff\xff\xff\xff\xbc\xdbW\x20\xff\xff\xff\xff\xbd\xb8\xd3\x20\xff\xff\xff\xff\xbe\xb1\xfe\xa0\xff\xff\xff\xff\xbf\x98\xb5\x20\xff\xff\xff\xff\xc0\x9b\x1b\x20\xff\xff\xff\xff\xc1x\x97\x20\xff\xff\xff\xff\xc2z\xfd\x20\xff\xff\xff\xff\xc3Xy\x20\xff\xff\xff\xff\xc4Q\xa4\xa0\xff\xff\xff\xff\xc58[\x20\xff\xff\xff\xff\xc6:\xc1\x20\xff\xff\xff\xff\xc7X\xd6\xa0\xff\xff\xff\xff\xc7\xda\x09\xa0\xff\xff\xff\xff\xd4I\xe0\x20\xff\xff\xff\xff\xd5\x1e!\xa0\xff\xff\xff\xff\xd6N\xac\x20\xff\xff\xff\xff\xd7,(\x20\xff\xff\xff\xff\xd8.\x8e\x20\xff\xff\xff\xff\xd8\xf9\x95\x20\xff\xff\xff\xff\xda\x0ep\x20\xff\xff\xff\xff\xda\xeb\xec\x20\xff\xff\xff\xff\xdb\xe5\x17\xa0\xff\xff\xff\xff\xdc\xcb\xce\x20\xff\xff\xff\xff\xdd\xc4\xf9\xa0\xff\xff\xff\xff\xde\xb4\xea\xa0\xff\xff\xff\xff\xdf\xae\x16\x20\xff\xff\xff\xff\xe0\x94\xcc\xa0\xff\xff\xff\xff\xe1rH\xa0\xff\xff\xff\xff\xe2kt\x20\xff\xff\xff\xff\xe3R*\xa0\xff\xff\xff\xff\xe4T\x90\xa0\xff\xff\xff\xff\xe52\x0c\xa0\xff\xff\xff\xff\xe6=\xad\x20\xff\xff\xff\xff\xe7\x1b)\x20\xff\xff\xff\xff\xe8\x14T\xa0\xff\xff\xff\xff\xe8\xfb\x0b\x20\xff\xff\xff\xff\xe9\xfdq\x20\xff\xff\xff\xff\xea\xda\xed\x20\xff\xff\xff\xff\xeb\xddS\x20\xff\xff\xff\xff\xec\xba\xcf\x20\xff\xff\xff\xff\xed\xb3\xfa\xa0\xff\xff\xff\xff\xee\x9a\xb1\x20\xff\xff\xff\xff\xef\x81g\xa0\xff\xff\xff\xff\xf0\x9f}\x20\xff\xff\xff\xff\xf1aI\xa0\xff\xff\xff\xff\xf2\x7f_\x20\xff\xff\xff\xff\xf3Jf\x20\xff\xff\xff\xff\xf4_A\x20\xff\xff\xff\xff\xf5!\x0d\xa0\xff\xff\xff\xff\xf6?#\x20\xff\xff\xff\xff\xf7\x00\xef\xa0\xff\xff\xff\xff\xf8\x1f\x05\x20\xff\xff\xff\xff\xf8\xe0\xd1\xa0\xff\xff\xff\xff\xf9\xfe\xe7\x20\xff\xff\xff\xff\xfa\xc0\xb3\xa0\xff\xff\xff\xff\xfb\xe8\x03\xa0\xff\xff\xff\xff\xfc{\xab\xa0\xff\xff\xff\xff\xfd\xc7\xbbp\x00\x00\x00\x00\x03p\xc6\x20\x00\x00\x00\x00\x04)X\x20\x00\x00\x00\x00\x05P\xa8\x20\x00\x00\x00\x00\x06\x09:\x20\x00\x00\x00\x00\x070\x8a\x20\x00\x00\x00\x00\x07\xe9\x1c\x20\x00\x00\x00\x00\x09\x10l\x20\x00\x00\x00\x00\x09\xc8\xfe\x20\x00\x00\x00\x00\n\xf0N\x20\x00\x00\x00\x00\x0b\xb2\x1a\xa0\x00\x00\x00\x00\x0c\xd00\x20\x00\x00\x00\x00\x0d\x91\xfc\xa0\x00\x00\x00\x00\x0e\xb0\x12\x20\x00\x00\x00\x00\x0fq\xde\xa0\x00\x00\x00\x00\x10\x99.\xa0\x00\x00\x00\x00\x11Q\xc0\xa0\x00\x00\x00\x00\x12y\x10\xa0\x00\x00\x00\x00\x131\xa2\xa0\x00\x00\x00\x00\x14X\xf2\xa0\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x168\xc6\x90\x00\x00\x00\x00\x17\x03\xcd\x90\x00\x00\x00\x00\x18\x18\xa8\x90\x00\x00\x00\x00\x18\xe3\xaf\x90\x00\x00\x00\x00\x19\xf8\x8a\x90\x00\x00\x00\x00\x1a\xc3\x91\x90\x00\x00\x00\x00\x1b\xe1\xa7\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\xc1\x89\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f\xa1k\x10\x00\x00\x00\x00\x20lr\x10\x00\x00\x00\x00!\x81M\x10\x00\x00\x00\x00\x22LT\x10\x00\x00\x00\x00#a/\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%JK\x90\x00\x00\x00\x00&\x0c\x18\x10\x00\x00\x00\x00'*-\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00)\n\x0f\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xe9\xf1\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xc9\xd3\x90\x00\x00\x00\x00-\x94\xda\x90\x00\x00\x00\x00.\xa9\xb5\x90\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000\x89\x97\x90\x00\x00\x00\x001]\xd9\x10\x01\x02\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x07\x06\x07\x06\x07\x06\x07\x06\x07\x06\x07\x06\x07\x06\x07\x06\x07\x06\x07\x06\x07\x06\x07\x06\x07\x06\x07\x06\x07\x06\x07\x06\x07\x06\x07\x06\x07\x06\x07\x06\x07\x06\x07\x06\x07\x06\x07\x06\x07\x06\x07\xff\xff\xfa$\x00\x00\xff\xff\xfa\x0f\x00\x04\x00\x00\x08\x1f\x01\x08\x00\x00\x0e\x10\x01\x0c\x00\x00\x00\x00\x00\x10\x00\x00\x0e\x10\x01\x08\x00\x00\x00\x00\x01\x10\x00\x00\x0e\x10\x00\x08LMT\x00DMT\x00IST\x00BST\x00GMT\x00\nIST-1GMT0,M10.5.0,M3.5.0/1\n",
++ date: func(loc *time.Location) time.Time { return time.Date(2021, time.April, 2, 11, 12, 13, 0, loc) },
++ wantName: "IST",
++ wantOffset: 3600,
++ },
+ }
+
+ func TestLoadLocationFromTZDataSlim(t *testing.T) {
+@@ -219,7 +231,7 @@ func TestLoadLocationFromTZDataSlim(t *testing.T) {
+ t.Fatal(err)
+ }
+
+- d := time.Date(2020, time.October, 29, 15, 30, 0, 0, reference)
++ d := test.date(reference)
+ tzName, tzOffset := d.Zone()
+ if tzName != test.wantName {
+ t.Errorf("Zone name == %s, want %s", tzName, test.wantName)
+@@ -239,20 +251,21 @@ func TestTzset(t *testing.T) {
+ off int
+ start int64
+ end int64
++ isDST bool
+ ok bool
+ }{
+- {"", 0, 0, "", 0, 0, 0, false},
+- {"PST8PDT,M3.2.0,M11.1.0", 0, 2159200800, "PDT", -7 * 60 * 60, 2152173600, 2172733200, true},
+- {"PST8PDT,M3.2.0,M11.1.0", 0, 2152173599, "PST", -8 * 60 * 60, 2145916800, 2152173600, true},
+- {"PST8PDT,M3.2.0,M11.1.0", 0, 2152173600, "PDT", -7 * 60 * 60, 2152173600, 2172733200, true},
+- {"PST8PDT,M3.2.0,M11.1.0", 0, 2152173601, "PDT", -7 * 60 * 60, 2152173600, 2172733200, true},
+- {"PST8PDT,M3.2.0,M11.1.0", 0, 2172733199, "PDT", -7 * 60 * 60, 2152173600, 2172733200, true},
+- {"PST8PDT,M3.2.0,M11.1.0", 0, 2172733200, "PST", -8 * 60 * 60, 2172733200, 2177452800, true},
+- {"PST8PDT,M3.2.0,M11.1.0", 0, 2172733201, "PST", -8 * 60 * 60, 2172733200, 2177452800, true},
++ {"", 0, 0, "", 0, 0, 0, false, false},
++ {"PST8PDT,M3.2.0,M11.1.0", 0, 2159200800, "PDT", -7 * 60 * 60, 2152173600, 2172733200, true, true},
++ {"PST8PDT,M3.2.0,M11.1.0", 0, 2152173599, "PST", -8 * 60 * 60, 2145916800, 2152173600, false, true},
++ {"PST8PDT,M3.2.0,M11.1.0", 0, 2152173600, "PDT", -7 * 60 * 60, 2152173600, 2172733200, true, true},
++ {"PST8PDT,M3.2.0,M11.1.0", 0, 2152173601, "PDT", -7 * 60 * 60, 2152173600, 2172733200, true, true},
++ {"PST8PDT,M3.2.0,M11.1.0", 0, 2172733199, "PDT", -7 * 60 * 60, 2152173600, 2172733200, true, true},
++ {"PST8PDT,M3.2.0,M11.1.0", 0, 2172733200, "PST", -8 * 60 * 60, 2172733200, 2177452800, false, true},
++ {"PST8PDT,M3.2.0,M11.1.0", 0, 2172733201, "PST", -8 * 60 * 60, 2172733200, 2177452800, false, true},
+ } {
+- name, off, start, end, ok := time.Tzset(test.inStr, test.inEnd, test.inSec)
+- if name != test.name || off != test.off || start != test.start || end != test.end || ok != test.ok {
+- t.Errorf("tzset(%q, %d, %d) = %q, %d, %d, %d, %t, want %q, %d, %d, %d, %t", test.inStr, test.inEnd, test.inSec, name, off, start, end, ok, test.name, test.off, test.start, test.end, test.ok)
++ name, off, start, end, isDST, ok := time.Tzset(test.inStr, test.inEnd, test.inSec)
++ if name != test.name || off != test.off || start != test.start || end != test.end || isDST != test.isDST || ok != test.ok {
++ t.Errorf("tzset(%q, %d, %d) = %q, %d, %d, %d, %t, %t, want %q, %d, %d, %d, %t, %t", test.inStr, test.inEnd, test.inSec, name, off, start, end, isDST, ok, test.name, test.off, test.start, test.end, test.isDST, test.ok)
+ }
+ }
+ }
+--
+2.27.0
+
diff --git a/0038-release-branch.go1.15-std-update-golang.org-x-net-to.patch b/0038-release-branch.go1.15-std-update-golang.org-x-net-to.patch
new file mode 100644
index 0000000..fe2ee89
--- /dev/null
+++ b/0038-release-branch.go1.15-std-update-golang.org-x-net-to.patch
@@ -0,0 +1,97 @@
+From 5aed4ce3c854bdbbb6dd5c1ccfa15c23d4b6c989 Mon Sep 17 00:00:00 2001
+From: Katie Hockman
+Date: Wed, 28 Apr 2021 14:47:48 -0400
+Subject: [PATCH 38/44] [release-branch.go1.15] std: update golang.org/x/net to
+ 20210428183841-261fb518b1ed
+
+Steps:
+ go get -d golang.org/x/net@release-branch.go1.15
+ go mod tidy
+ go mod vendor
+
+This http2 bundle does not need to be updated.
+
+Fixes #45711
+
+Change-Id: I085ca592dfc8d5d9c328a7979142e88e7130a813
+Reviewed-on: https://go-review.googlesource.com/c/go/+/314790
+Trust: Katie Hockman
+Run-TryBot: Katie Hockman
+Reviewed-by: Dmitri Shuralyov
+
+Conflict:NA
+Reference:https://github.com/golang/go/commit/5aed4ce3c854bdbbb6dd5c1ccfa15c23d4b6c989
+
+---
+ src/go.mod | 2 +-
+ src/go.sum | 4 ++--
+ src/vendor/golang.org/x/net/http/httpguts/httplex.go | 10 ++++++----
+ src/vendor/modules.txt | 2 +-
+ 4 files changed, 10 insertions(+), 8 deletions(-)
+
+diff --git a/src/go.mod b/src/go.mod
+index 6b97366bbe..dfcba7a1c8 100644
+--- a/src/go.mod
++++ b/src/go.mod
+@@ -4,7 +4,7 @@ go 1.15
+
+ require (
+ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9
+- golang.org/x/net v0.0.0-20201008223702-a5fa9d4b7c91
++ golang.org/x/net v0.0.0-20210428183841-261fb518b1ed
+ golang.org/x/sys v0.0.0-20200501145240-bc7a7d42d5c3 // indirect
+ golang.org/x/text v0.3.3-0.20200430171850-afb9336c4530 // indirect
+ )
+diff --git a/src/go.sum b/src/go.sum
+index fbd3279aad..47e918848c 100644
+--- a/src/go.sum
++++ b/src/go.sum
+@@ -2,8 +2,8 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk
+ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI=
+ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+-golang.org/x/net v0.0.0-20201008223702-a5fa9d4b7c91 h1:zd7kl5i5PDM0OnFbRWVM6B8mXojzv8LOkHN9LsOrRf4=
+-golang.org/x/net v0.0.0-20201008223702-a5fa9d4b7c91/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
++golang.org/x/net v0.0.0-20210428183841-261fb518b1ed h1:aunM0N/jnRHvQgZo3kYkfaAGet2kIMFOPIbopG5BhYw=
++golang.org/x/net v0.0.0-20210428183841-261fb518b1ed/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
+ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+ golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+ golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+diff --git a/src/vendor/golang.org/x/net/http/httpguts/httplex.go b/src/vendor/golang.org/x/net/http/httpguts/httplex.go
+index e7de24ee64..c79aa73f28 100644
+--- a/src/vendor/golang.org/x/net/http/httpguts/httplex.go
++++ b/src/vendor/golang.org/x/net/http/httpguts/httplex.go
+@@ -137,11 +137,13 @@ func trimOWS(x string) string {
+ // contains token amongst its comma-separated tokens, ASCII
+ // case-insensitively.
+ func headerValueContainsToken(v string, token string) bool {
+- v = trimOWS(v)
+- if comma := strings.IndexByte(v, ','); comma != -1 {
+- return tokenEqual(trimOWS(v[:comma]), token) || headerValueContainsToken(v[comma+1:], token)
++ for comma := strings.IndexByte(v, ','); comma != -1; comma = strings.IndexByte(v, ',') {
++ if tokenEqual(trimOWS(v[:comma]), token) {
++ return true
++ }
++ v = v[comma+1:]
+ }
+- return tokenEqual(v, token)
++ return tokenEqual(trimOWS(v), token)
+ }
+
+ // lowerASCII returns the ASCII lowercase version of b.
+diff --git a/src/vendor/modules.txt b/src/vendor/modules.txt
+index 03ca3c3ae4..dd2296b694 100644
+--- a/src/vendor/modules.txt
++++ b/src/vendor/modules.txt
+@@ -8,7 +8,7 @@ golang.org/x/crypto/curve25519
+ golang.org/x/crypto/hkdf
+ golang.org/x/crypto/internal/subtle
+ golang.org/x/crypto/poly1305
+-# golang.org/x/net v0.0.0-20201008223702-a5fa9d4b7c91
++# golang.org/x/net v0.0.0-20210428183841-261fb518b1ed
+ ## explicit
+ golang.org/x/net/dns/dnsmessage
+ golang.org/x/net/http/httpguts
+--
+2.27.0
+
diff --git a/0039-release-branch.go1.15-runtime-time-disable-preemptio.patch b/0039-release-branch.go1.15-runtime-time-disable-preemptio.patch
new file mode 100644
index 0000000..bde920d
--- /dev/null
+++ b/0039-release-branch.go1.15-runtime-time-disable-preemptio.patch
@@ -0,0 +1,95 @@
+From 72ccabc99449b2cb5bb1438eb90244d55f7b02f5 Mon Sep 17 00:00:00 2001
+From: Michael Pratt
+Date: Wed, 10 Mar 2021 16:06:47 -0500
+Subject: [PATCH 39/44] [release-branch.go1.15] runtime, time: disable
+ preemption in addtimer
+
+The timerpMask optimization updates a mask of Ps (potentially)
+containing timers in pidleget / pidleput. For correctness, it depends on
+the assumption that new timers can only be added to a P's own heap.
+
+addtimer violates this assumption if it is preempted after computing pp.
+That G may then run on a different P, but adding a timer to the original
+P's heap.
+
+Avoid this by disabling preemption while pp is in use.
+
+Other uses of doaddtimer should be OK:
+
+* moveTimers: always moves to the current P's heap
+* modtimer, cleantimers, addAdjustedTimers, runtimer: does not add net
+ new timers to the heap while locked
+
+For #44868
+Fixes #45731
+
+Change-Id: I4a5d080865e854931d0a3a09a51ca36879101d72
+Reviewed-on: https://go-review.googlesource.com/c/go/+/300610
+Trust: Michael Pratt
+Run-TryBot: Michael Pratt
+Reviewed-by: Michael Knyszek
+Reviewed-by: Ian Lance Taylor
+TryBot-Result: Go Bot
+Reviewed-on: https://go-review.googlesource.com/c/go/+/313129
+Trust: Ian Lance Taylor
+Run-TryBot: Ian Lance Taylor
+Reviewed-by: Michael Pratt
+
+Conflict:NA
+Reference:https://github.com/golang/go/commit/72ccabc99449b2cb5bb1438eb90244d55f7b02f5
+
+---
+ src/runtime/time.go | 5 +++++
+ src/time/sleep_test.go | 16 ++++++++++++++++
+ 2 files changed, 21 insertions(+)
+
+diff --git a/src/runtime/time.go b/src/runtime/time.go
+index ec3eae9cca..de7468d129 100644
+--- a/src/runtime/time.go
++++ b/src/runtime/time.go
+@@ -254,6 +254,9 @@ func addtimer(t *timer) {
+
+ when := t.when
+
++ // Disable preemption while using pp to avoid changing another P's heap.
++ mp := acquirem()
++
+ pp := getg().m.p.ptr()
+ lock(&pp.timersLock)
+ cleantimers(pp)
+@@ -261,6 +264,8 @@ func addtimer(t *timer) {
+ unlock(&pp.timersLock)
+
+ wakeNetPoller(when)
++
++ releasem(mp)
+ }
+
+ // doaddtimer adds t to the current P's heap.
+diff --git a/src/time/sleep_test.go b/src/time/sleep_test.go
+index f5678020b9..ea253f8709 100644
+--- a/src/time/sleep_test.go
++++ b/src/time/sleep_test.go
+@@ -501,3 +501,19 @@ func TestZeroTimerStopPanics(t *testing.T) {
+ var tr Timer
+ tr.Stop()
+ }
++
++// Test that zero duration timers aren't missed by the scheduler. Regression test for issue 44868.
++func TestZeroTimer(t *testing.T) {
++ if testing.Short() {
++ t.Skip("-short")
++ }
++
++ for i := 0; i < 1000000; i++ {
++ s := Now()
++ ti := NewTimer(0)
++ <-ti.C
++ if diff := Since(s); diff > 2*Second {
++ t.Errorf("Expected time to get value from Timer channel in less than 2 sec, took %v", diff)
++ }
++ }
++}
+--
+2.27.0
+
diff --git a/0040-release-branch.go1.15-runtime-non-strict-InlTreeInde.patch b/0040-release-branch.go1.15-runtime-non-strict-InlTreeInde.patch
new file mode 100644
index 0000000..e13ccf7
--- /dev/null
+++ b/0040-release-branch.go1.15-runtime-non-strict-InlTreeInde.patch
@@ -0,0 +1,54 @@
+From c0a7ecfae775a9d50d338e8123fac32a5d04308c Mon Sep 17 00:00:00 2001
+From: Michael Pratt
+Date: Fri, 9 Apr 2021 17:01:45 -0400
+Subject: [PATCH 40/44] [release-branch.go1.15] runtime: non-strict
+ InlTreeIndex lookup in expandFinalInlineFrame
+
+This is a follow-up to golang.org/cl/301369, which made the same change
+in Frames.Next. The same logic applies here: a profile stack may have
+been truncated at an invalid PC provided by cgoTraceback.
+expandFinalInlineFrame will then try to lookup the inline tree and
+crash.
+
+The same fix applies as well: upon encountering a bad PC, simply leave
+it as-is and move on.
+
+For #44971
+For #45480
+Fixes #45481
+
+Change-Id: I2823c67a1f3425466b05384cc6d30f5fc8ee6ddc
+Reviewed-on: https://go-review.googlesource.com/c/go/+/309109
+Reviewed-by: Michael Knyszek
+Trust: Michael Pratt
+(cherry picked from commit aad13cbb749d1e6c085ff0556d306de1a2d5d063)
+Reviewed-on: https://go-review.googlesource.com/c/go/+/309550
+Run-TryBot: Michael Pratt
+Reviewed-by: Cherry Zhang
+TryBot-Result: Go Bot
+
+Conflict:NA
+Reference:https://github.com/golang/go/commit/c0a7ecfae775a9d50d338e8123fac32a5d04308c
+
+---
+ src/runtime/symtab.go | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/src/runtime/symtab.go b/src/runtime/symtab.go
+index c77d513e74..75772f4fd8 100644
+--- a/src/runtime/symtab.go
++++ b/src/runtime/symtab.go
+@@ -185,7 +185,9 @@ func runtime_expandFinalInlineFrame(stk []uintptr) []uintptr {
+ var cache pcvalueCache
+ inltree := (*[1 << 20]inlinedCall)(inldata)
+ for {
+- ix := pcdatavalue(f, _PCDATA_InlTreeIndex, tracepc, &cache)
++ // Non-strict as cgoTraceback may have added bogus PCs
++ // with a valid funcInfo but invalid PCDATA.
++ ix := pcdatavalue1(f, _PCDATA_InlTreeIndex, tracepc, &cache, false)
+ if ix < 0 {
+ break
+ }
+--
+2.27.0
+
diff --git a/0041-release-branch.go1.15-runtime-pprof-skip-tests-for-A.patch b/0041-release-branch.go1.15-runtime-pprof-skip-tests-for-A.patch
new file mode 100644
index 0000000..dd2edf4
--- /dev/null
+++ b/0041-release-branch.go1.15-runtime-pprof-skip-tests-for-A.patch
@@ -0,0 +1,48 @@
+From ba7cac469b399b36e8d3e40ac57eb11688c53e00 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Cl=C3=A9ment=20Chigot?=
+Date: Thu, 1 Apr 2021 10:06:05 +0200
+Subject: [PATCH 41/44] [release-branch.go1.15] runtime/pprof: skip tests for
+ AIX
+
+Most of the time, the pprof tests are passing, except
+for the builder. The reason is still unknown but I'd rather release
+the builder to avoid missing other more important bugs.
+
+Updates #45170
+
+Change-Id: I667543ee1ae309b7319c5b3676a0901b4d0ecf2e
+Reviewed-on: https://go-review.googlesource.com/c/go/+/306489
+Run-TryBot: Tobias Klauser
+TryBot-Result: Go Bot
+Reviewed-by: Cherry Zhang
+Trust: Lynn Boger
+(cherry picked from commit 7bfd681c2f11918c6245ad2906b2efc12eda2914)
+Reviewed-on: https://go-review.googlesource.com/c/go/+/317369
+Reviewed-by: Heschi Kreinick
+Trust: Dmitri Shuralyov
+Run-TryBot: Dmitri Shuralyov
+
+Conflict:NA
+Reference:https://github.com/golang/go/commit/ba7cac469b399b36e8d3e40ac57eb11688c53e00
+
+---
+ src/runtime/pprof/pprof_test.go | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/src/runtime/pprof/pprof_test.go b/src/runtime/pprof/pprof_test.go
+index 7149bfb31f..9c1c097206 100644
+--- a/src/runtime/pprof/pprof_test.go
++++ b/src/runtime/pprof/pprof_test.go
+@@ -280,7 +280,8 @@ func testCPUProfile(t *testing.T, matches matchFunc, need []string, avoid []stri
+
+ broken := false
+ switch runtime.GOOS {
+- case "darwin", "dragonfly", "netbsd", "illumos", "solaris":
++ // See https://golang.org/issue/45170 for AIX.
++ case "darwin", "dragonfly", "netbsd", "illumos", "solaris", "aix":
+ broken = true
+ case "openbsd":
+ if runtime.GOARCH == "arm" || runtime.GOARCH == "arm64" {
+--
+2.27.0
+
diff --git a/0043-release-branch.go1.15-math-big-fix-TestShiftOverlap-.patch b/0043-release-branch.go1.15-math-big-fix-TestShiftOverlap-.patch
new file mode 100644
index 0000000..61e4a76
--- /dev/null
+++ b/0043-release-branch.go1.15-math-big-fix-TestShiftOverlap-.patch
@@ -0,0 +1,65 @@
+From 44a6805ca92b00f30d5ed3f9e8d0b464d3f402bf Mon Sep 17 00:00:00 2001
+From: SparrowLii
+Date: Mon, 24 Aug 2020 14:43:32 +0800
+Subject: [PATCH 43/44] [release-branch.go1.15] math/big: fix TestShiftOverlap
+ for test -count arguments > 1
+
+Don't overwrite incoming test data.
+
+The change uses copy instead of assigning statement to avoid this.
+
+For #45335
+
+Change-Id: Ib907101822d811de5c45145cb9d7961907e212c3
+Reviewed-on: https://go-review.googlesource.com/c/go/+/250137
+Run-TryBot: Emmanuel Odeke
+TryBot-Result: Gobot Gobot
+Reviewed-by: Robert Griesemer
+(cherry picked from commit 41bc0a1713b9436e96c2d64211ad94e42cafd591)
+Reviewed-on: https://go-review.googlesource.com/c/go/+/319831
+Run-TryBot: Carlos Amedee
+TryBot-Result: Go Bot
+Trust: Carlos Amedee
+Reviewed-by: Jonathan Albrecht
+Reviewed-by: Emmanuel Odeke
+
+Conflict:NA
+Reference:https://github.com/golang/go/commit/44a6805ca92b00f30d5ed3f9e8d0b464d3f402bf
+
+---
+ src/math/big/arith_test.go | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/src/math/big/arith_test.go b/src/math/big/arith_test.go
+index 05136f1895..e2b982c89c 100644
+--- a/src/math/big/arith_test.go
++++ b/src/math/big/arith_test.go
+@@ -241,20 +241,20 @@ var argshrVU = []argVU{
+ }
+
+ func testShiftFunc(t *testing.T, f func(z, x []Word, s uint) Word, a argVU) {
+- // save a.d for error message, or it will be overwritten.
++ // work on copy of a.d to preserve the original data.
+ b := make([]Word, len(a.d))
+ copy(b, a.d)
+- z := a.d[a.zp : a.zp+a.l]
+- x := a.d[a.xp : a.xp+a.l]
++ z := b[a.zp : a.zp+a.l]
++ x := b[a.xp : a.xp+a.l]
+ c := f(z, x, a.s)
+ for i, zi := range z {
+ if zi != a.r[i] {
+- t.Errorf("d := %v, %s(d[%d:%d], d[%d:%d], %d)\n\tgot z[%d] = %#x; want %#x", b, a.m, a.zp, a.zp+a.l, a.xp, a.xp+a.l, a.s, i, zi, a.r[i])
++ t.Errorf("d := %v, %s(d[%d:%d], d[%d:%d], %d)\n\tgot z[%d] = %#x; want %#x", a.d, a.m, a.zp, a.zp+a.l, a.xp, a.xp+a.l, a.s, i, zi, a.r[i])
+ break
+ }
+ }
+ if c != a.c {
+- t.Errorf("d := %v, %s(d[%d:%d], d[%d:%d], %d)\n\tgot c = %#x; want %#x", b, a.m, a.zp, a.zp+a.l, a.xp, a.xp+a.l, a.s, c, a.c)
++ t.Errorf("d := %v, %s(d[%d:%d], d[%d:%d], %d)\n\tgot c = %#x; want %#x", a.d, a.m, a.zp, a.zp+a.l, a.xp, a.xp+a.l, a.s, c, a.c)
+ }
+ }
+
+--
+2.27.0
+
diff --git a/0044-release-branch.go1.15-math-big-remove-the-s390x-asse.patch b/0044-release-branch.go1.15-math-big-remove-the-s390x-asse.patch
new file mode 100644
index 0000000..799505e
--- /dev/null
+++ b/0044-release-branch.go1.15-math-big-remove-the-s390x-asse.patch
@@ -0,0 +1,337 @@
+From 963687891319d118c20a2a71f0234ceb3a8dade4 Mon Sep 17 00:00:00 2001
+From: Jonathan Albrecht
+Date: Wed, 2 Dec 2020 10:44:10 -0500
+Subject: [PATCH 44/44] [release-branch.go1.15] math/big: remove the s390x
+ assembly for shlVU and shrVU
+
+The s390x assembly for shlVU does a forward copy when the shift amount s
+is 0. This causes corruption of the result z when z is aliased to the
+input x.
+
+This fix removes the s390x assembly for both shlVU and shrVU so the pure
+go implementations will be used.
+
+Test cases have been added to the existing TestShiftOverlap test to
+cover shift values of 0, 1 and (_W - 1).
+
+Fixes #45335
+
+Change-Id: I75ca0e98f3acfaa6366a26355dcd9dd82499a48b
+Reviewed-on: https://go-review.googlesource.com/c/go/+/274442
+Run-TryBot: Robert Griesemer
+TryBot-Result: Go Bot
+Reviewed-by: Robert Griesemer
+Reviewed-by: Matthew Dempsky
+Trust: Robert Griesemer
+(cherry picked from commit b1369d5862bc78eaa902ae637c874e6a6133f1f9)
+Reviewed-on: https://go-review.googlesource.com/c/go/+/320169
+Trust: Carlos Amedee
+Run-TryBot: Carlos Amedee
+Reviewed-by: Dmitri Shuralyov
+
+Conflict:NA
+Reference:https://github.com/golang/go/commit/963687891319d118c20a2a71f0234ceb3a8dade4
+
+---
+ src/math/big/arith_s390x.s | 192 +------------------------------------
+ src/math/big/arith_test.go | 55 ++++++++++-
+ 2 files changed, 54 insertions(+), 193 deletions(-)
+
+diff --git a/src/math/big/arith_s390x.s b/src/math/big/arith_s390x.s
+index 4891768111..153c42679c 100644
+--- a/src/math/big/arith_s390x.s
++++ b/src/math/big/arith_s390x.s
+@@ -702,199 +702,11 @@ returnC:
+
+ // func shlVU(z, x []Word, s uint) (c Word)
+ TEXT ·shlVU(SB), NOSPLIT, $0
+- MOVD z_len+8(FP), R5
+- MOVD $0, R0
+- SUB $1, R5 // n--
+- BLT X8b // n < 0 (n <= 0)
+-
+- // n > 0
+- MOVD s+48(FP), R4
+- CMPBEQ R0, R4, Z80 // handle 0 case beq
+- MOVD $64, R6
+- CMPBEQ R6, R4, Z864 // handle 64 case beq
+- MOVD z+0(FP), R2
+- MOVD x+24(FP), R8
+- SLD $3, R5 // n = n*8
+- SUB R4, R6, R7
+- MOVD (R8)(R5*1), R10 // w1 = x[i-1]
+- SRD R7, R10, R3
+- MOVD R3, c+56(FP)
+-
+- MOVD $0, R1 // i = 0
+- BR E8
+-
+- // i < n-1
+-L8:
+- MOVD R10, R3 // w = w1
+- MOVD -8(R8)(R5*1), R10 // w1 = x[i+1]
+-
+- SLD R4, R3 // w<>ŝ
+- SRD R7, R10, R6
+- OR R6, R3
+- MOVD R3, (R2)(R5*1) // z[i] = w<>ŝ
+- SUB $8, R5 // i--
+-
+-E8:
+- CMPBGT R5, R0, L8 // i < n-1
+-
+- // i >= n-1
+-X8a:
+- SLD R4, R10 // w1<= n-1
+- MOVD R10, (R2)(R5*1)
+- RET
+-
+-Z864:
+- MOVD z+0(FP), R2
+- MOVD x+24(FP), R8
+- SLD $3, R5 // n = n*8
+- MOVD (R8)(R5*1), R3 // w1 = x[n-1]
+- MOVD R3, c+56(FP) // z[i] = x[n-1]
+-
+- BR E864
+-
+- // i < n-1
+-L864:
+- MOVD -8(R8)(R5*1), R3
+-
+- MOVD R3, (R2)(R5*1) // z[i] = x[n-1]
+- SUB $8, R5 // i--
+-
+-E864:
+- CMPBGT R5, R0, L864 // i < n-1
+-
+- MOVD R0, (R2) // z[n-1] = 0
+- RET
++ BR ·shlVU_g(SB)
+
+-// CX = R4, r8 = r8, r10 = r2 , r11 = r5, DX = r3, AX = r10 , BX = R1 , 64-count = r7 (R0 set to 0) temp = R6
+ // func shrVU(z, x []Word, s uint) (c Word)
+ TEXT ·shrVU(SB), NOSPLIT, $0
+- MOVD z_len+8(FP), R5
+- MOVD $0, R0
+- SUB $1, R5 // n--
+- BLT X9b // n < 0 (n <= 0)
+-
+- // n > 0
+- MOVD s+48(FP), R4
+- CMPBEQ R0, R4, ZB0 // handle 0 case beq
+- MOVD $64, R6
+- CMPBEQ R6, R4, ZB64 // handle 64 case beq
+- MOVD z+0(FP), R2
+- MOVD x+24(FP), R8
+- SLD $3, R5 // n = n*8
+- SUB R4, R6, R7
+- MOVD (R8), R10 // w1 = x[0]
+- SLD R7, R10, R3
+- MOVD R3, c+56(FP)
+-
+- MOVD $0, R1 // i = 0
+- BR E9
+-
+- // i < n-1
+-L9:
+- MOVD R10, R3 // w = w1
+- MOVD 8(R8)(R1*1), R10 // w1 = x[i+1]
+-
+- SRD R4, R3 // w>>s | w1<>s | w1<= n-1
+-X9a:
+- SRD R4, R10 // w1>>s
+- MOVD R10, (R2)(R5*1) // z[n-1] = w1>>s
+- RET
+-
+-X9b:
+- MOVD R0, c+56(FP)
+- RET
+-
+-ZB0:
+- MOVD z+0(FP), R2
+- MOVD x+24(FP), R8
+- SLD $3, R5 // n = n*8
+-
+- MOVD (R8), R10 // w1 = x[0]
+- MOVD $0, R3 // R10 << 64
+- MOVD R3, c+56(FP)
+-
+- MOVD $0, R1 // i = 0
+- BR E9Z
+-
+- // i < n-1
+-L9Z:
+- MOVD R10, R3 // w = w1
+- MOVD 8(R8)(R1*1), R10 // w1 = x[i+1]
+-
+- MOVD R3, (R2)(R1*1) // z[i] = w>>s | w1<= n-1
+- MOVD R10, (R2)(R5*1) // z[n-1] = w1>>s
+- RET
+-
+-ZB64:
+- MOVD z+0(FP), R2
+- MOVD x+24(FP), R8
+- SLD $3, R5 // n = n*8
+- MOVD (R8), R3 // w1 = x[0]
+- MOVD R3, c+56(FP)
+-
+- MOVD $0, R1 // i = 0
+- BR E964
+-
+- // i < n-1
+-L964:
+- MOVD 8(R8)(R1*1), R3 // w1 = x[i+1]
+-
+- MOVD R3, (R2)(R1*1) // z[i] = w>>s | w1<