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<= n-1 +- MOVD $0, R10 // w1>>s +- MOVD R10, (R2)(R5*1) // z[n-1] = w1>>s +- RET ++ BR ·shrVU_g(SB) + + // CX = R4, r8 = r8, r9=r9, r10 = r2 , r11 = r5, DX = r3, AX = r6 , BX = R1 , (R0 set to 0) + use R11 + use R7 for i + // func mulAddVWW(z, x []Word, y, r Word) (c Word) +diff --git a/src/math/big/arith_test.go b/src/math/big/arith_test.go +index e2b982c89c..fbbaa0e122 100644 +--- a/src/math/big/arith_test.go ++++ b/src/math/big/arith_test.go +@@ -224,13 +224,36 @@ type argVU struct { + m string // message. + } + ++var argshlVUIn = []Word{1, 2, 4, 8, 16, 32, 64, 0, 0, 0} ++var argshlVUr0 = []Word{1, 2, 4, 8, 16, 32, 64} ++var argshlVUr1 = []Word{2, 4, 8, 16, 32, 64, 128} ++var argshlVUrWm1 = []Word{1 << (_W - 1), 0, 1, 2, 4, 8, 16} ++ + var argshlVU = []argVU{ + // test cases for shlVU + {[]Word{1, _M, _M, _M, _M, _M, 3 << (_W - 2), 0}, 7, 0, 0, 1, []Word{2, _M - 1, _M, _M, _M, _M, 1<<(_W-1) + 1}, 1, "complete overlap of shlVU"}, + {[]Word{1, _M, _M, _M, _M, _M, 3 << (_W - 2), 0, 0, 0, 0}, 7, 0, 3, 1, []Word{2, _M - 1, _M, _M, _M, _M, 1<<(_W-1) + 1}, 1, "partial overlap by half of shlVU"}, + {[]Word{1, _M, _M, _M, _M, _M, 3 << (_W - 2), 0, 0, 0, 0, 0, 0, 0}, 7, 0, 6, 1, []Word{2, _M - 1, _M, _M, _M, _M, 1<<(_W-1) + 1}, 1, "partial overlap by 1 Word of shlVU"}, + {[]Word{1, _M, _M, _M, _M, _M, 3 << (_W - 2), 0, 0, 0, 0, 0, 0, 0, 0}, 7, 0, 7, 1, []Word{2, _M - 1, _M, _M, _M, _M, 1<<(_W-1) + 1}, 1, "no overlap of shlVU"}, +-} ++ // additional test cases with shift values of 0, 1 and (_W-1) ++ {argshlVUIn, 7, 0, 0, 0, argshlVUr0, 0, "complete overlap of shlVU and shift of 0"}, ++ {argshlVUIn, 7, 0, 0, 1, argshlVUr1, 0, "complete overlap of shlVU and shift of 1"}, ++ {argshlVUIn, 7, 0, 0, _W - 1, argshlVUrWm1, 32, "complete overlap of shlVU and shift of _W - 1"}, ++ {argshlVUIn, 7, 0, 1, 0, argshlVUr0, 0, "partial overlap by 6 Words of shlVU and shift of 0"}, ++ {argshlVUIn, 7, 0, 1, 1, argshlVUr1, 0, "partial overlap by 6 Words of shlVU and shift of 1"}, ++ {argshlVUIn, 7, 0, 1, _W - 1, argshlVUrWm1, 32, "partial overlap by 6 Words of shlVU and shift of _W - 1"}, ++ {argshlVUIn, 7, 0, 2, 0, argshlVUr0, 0, "partial overlap by 5 Words of shlVU and shift of 0"}, ++ {argshlVUIn, 7, 0, 2, 1, argshlVUr1, 0, "partial overlap by 5 Words of shlVU and shift of 1"}, ++ {argshlVUIn, 7, 0, 2, _W - 1, argshlVUrWm1, 32, "partial overlap by 5 Words of shlVU abd shift of _W - 1"}, ++ {argshlVUIn, 7, 0, 3, 0, argshlVUr0, 0, "partial overlap by 4 Words of shlVU and shift of 0"}, ++ {argshlVUIn, 7, 0, 3, 1, argshlVUr1, 0, "partial overlap by 4 Words of shlVU and shift of 1"}, ++ {argshlVUIn, 7, 0, 3, _W - 1, argshlVUrWm1, 32, "partial overlap by 4 Words of shlVU and shift of _W - 1"}, ++} ++ ++var argshrVUIn = []Word{0, 0, 0, 1, 2, 4, 8, 16, 32, 64} ++var argshrVUr0 = []Word{1, 2, 4, 8, 16, 32, 64} ++var argshrVUr1 = []Word{0, 1, 2, 4, 8, 16, 32} ++var argshrVUrWm1 = []Word{4, 8, 16, 32, 64, 128, 0} + + var argshrVU = []argVU{ + // test cases for shrVU +@@ -238,6 +261,19 @@ var argshrVU = []argVU{ + {[]Word{0, 0, 0, 0, 3, _M, _M, _M, _M, _M, 1 << (_W - 1)}, 7, 4, 1, 1, []Word{1<<(_W-1) + 1, _M, _M, _M, _M, _M >> 1, 1 << (_W - 2)}, 1 << (_W - 1), "partial overlap by half of shrVU"}, + {[]Word{0, 0, 0, 0, 0, 0, 0, 3, _M, _M, _M, _M, _M, 1 << (_W - 1)}, 7, 7, 1, 1, []Word{1<<(_W-1) + 1, _M, _M, _M, _M, _M >> 1, 1 << (_W - 2)}, 1 << (_W - 1), "partial overlap by 1 Word of shrVU"}, + {[]Word{0, 0, 0, 0, 0, 0, 0, 0, 3, _M, _M, _M, _M, _M, 1 << (_W - 1)}, 7, 8, 1, 1, []Word{1<<(_W-1) + 1, _M, _M, _M, _M, _M >> 1, 1 << (_W - 2)}, 1 << (_W - 1), "no overlap of shrVU"}, ++ // additional test cases with shift values of 0, 1 and (_W-1) ++ {argshrVUIn, 7, 3, 3, 0, argshrVUr0, 0, "complete overlap of shrVU and shift of 0"}, ++ {argshrVUIn, 7, 3, 3, 1, argshrVUr1, 1 << (_W - 1), "complete overlap of shrVU and shift of 1"}, ++ {argshrVUIn, 7, 3, 3, _W - 1, argshrVUrWm1, 2, "complete overlap of shrVU and shift of _W - 1"}, ++ {argshrVUIn, 7, 3, 2, 0, argshrVUr0, 0, "partial overlap by 6 Words of shrVU and shift of 0"}, ++ {argshrVUIn, 7, 3, 2, 1, argshrVUr1, 1 << (_W - 1), "partial overlap by 6 Words of shrVU and shift of 1"}, ++ {argshrVUIn, 7, 3, 2, _W - 1, argshrVUrWm1, 2, "partial overlap by 6 Words of shrVU and shift of _W - 1"}, ++ {argshrVUIn, 7, 3, 1, 0, argshrVUr0, 0, "partial overlap by 5 Words of shrVU and shift of 0"}, ++ {argshrVUIn, 7, 3, 1, 1, argshrVUr1, 1 << (_W - 1), "partial overlap by 5 Words of shrVU and shift of 1"}, ++ {argshrVUIn, 7, 3, 1, _W - 1, argshrVUrWm1, 2, "partial overlap by 5 Words of shrVU and shift of _W - 1"}, ++ {argshrVUIn, 7, 3, 0, 0, argshrVUr0, 0, "partial overlap by 4 Words of shrVU and shift of 0"}, ++ {argshrVUIn, 7, 3, 0, 1, argshrVUr1, 1 << (_W - 1), "partial overlap by 4 Words of shrVU and shift of 1"}, ++ {argshrVUIn, 7, 3, 0, _W - 1, argshrVUrWm1, 2, "partial overlap by 4 Words of shrVU and shift of _W - 1"}, + } + + func testShiftFunc(t *testing.T, f func(z, x []Word, s uint) Word, a argVU) { +@@ -274,11 +310,24 @@ func TestIssue31084(t *testing.T) { + // compute 10^n via 5^n << n. + const n = 165 + p := nat(nil).expNN(nat{5}, nat{n}, nil) +- p = p.shl(p, uint(n)) ++ p = p.shl(p, n) + got := string(p.utoa(10)) + want := "1" + strings.Repeat("0", n) + if got != want { +- t.Errorf("shl(%v, %v)\n\tgot %s; want %s\n", p, uint(n), got, want) ++ t.Errorf("shl(%v, %v)\n\tgot %s\n\twant %s", p, n, got, want) ++ } ++} ++ ++const issue42838Value = "159309191113245227702888039776771180559110455519261878607388585338616290151305816094308987472018268594098344692611135542392730712890625" ++ ++func TestIssue42838(t *testing.T) { ++ const s = 192 ++ z, _, _, _ := nat(nil).scan(strings.NewReader(issue42838Value), 0, false) ++ z = z.shl(z, s) ++ got := string(z.utoa(10)) ++ want := "1" + strings.Repeat("0", s) ++ if got != want { ++ t.Errorf("shl(%v, %v)\n\tgot %s\n\twant %s", z, s, got, want) + } + } + +-- +2.27.0 + diff --git a/0045-net-http-fix-hijack-hang-at-abortPendingRead.patch b/0045-net-http-fix-hijack-hang-at-abortPendingRead.patch new file mode 100644 index 0000000..a80c865 --- /dev/null +++ b/0045-net-http-fix-hijack-hang-at-abortPendingRead.patch @@ -0,0 +1,59 @@ +From 78770c121e8c2315d7bdf9e66870abffdaedbe9b Mon Sep 17 00:00:00 2001 +From: jingrui +Date: Thu, 20 May 2021 09:18:27 +0800 +Subject: [PATCH] net/http: fix hijack hang at abortPendingRead + +When concurrent many http requests which need hijack the connenction, +hijack may hang at abortPendingRead() on cr.cond.Wait(). + +The read can be from readRequest() from conn.serve() or +w.conn.r.startBackgroundRead(). especially in startBackgroundRead() +which always set the deadline time.Time{}. + +This problem seems easy reproduce on arm. + +Signed-off-by: jingrui + +Conflict:NA +Reference:https://github.com/golang/go/pull/46278/commits/78770c121e8c2315d7bdf9e66870abffdaedbe9b + +--- + src/net/http/server.go | 22 +++++++++++++++++++--- + 1 file changed, 19 insertions(+), 3 deletions(-) + +diff --git a/src/net/http/server.go b/src/net/http/server.go +index 4e73508973..01e7e10011 100644 +--- a/src/net/http/server.go ++++ b/src/net/http/server.go +@@ -736,9 +736,25 @@ func (cr *connReader) abortPendingRead() { + } + cr.aborted = true + cr.conn.rwc.SetReadDeadline(aLongTimeAgo) +- for cr.inRead { +- cr.cond.Wait() +- } ++ done := make(chan struct{}) ++ go func() { ++ for cr.inRead { ++ cr.cond.Wait() ++ } ++ close(done) ++ }() ++ ++ func() { ++ for { ++ select { ++ case <-done: ++ return ++ case <-time.After(100*time.Millisecond): ++ cr.conn.rwc.SetReadDeadline(aLongTimeAgo) ++ } ++ } ++ }() ++ + cr.conn.rwc.SetReadDeadline(time.Time{}) + } + +-- +2.27.0 + diff --git a/golang.spec b/golang.spec index 83f5764..2b11c09 100644 --- a/golang.spec +++ b/golang.spec @@ -62,7 +62,7 @@ Name: golang Version: 1.15.7 -Release: 3 +Release: 4 Summary: The Go Programming Language License: BSD and Public Domain URL: https://golang.org/ @@ -151,6 +151,49 @@ Requires: openEuler-rpm-config ExclusiveArch: %{golang_arches} +Patch6001: 0001-release-branch.go1.15-doc-go1.15-mention-1.15.3-cgo-.patch +Patch6002: 0002-release-branch.go1.15-cmd-go-fix-mod_get_fallback-te.patch +Patch6003: 0003-release-branch.go1.15-internal-execabs-only-run-test.patch +Patch6004: 0004-release-branch.go1.15-cmd-compile-don-t-short-circui.patch +Patch6005: 0005-release-branch.go1.15-cmd-go-fix-get_update_unknown_.patch +Patch6006: 0006-release-branch.go1.15-net-http-update-bundled-x-net-.patch +Patch6007: 0007-release-branch.go1.15-cmd-go-don-t-lookup-the-path-f.patch +Patch6008: 0008-release-branch.go1.15-cmd-link-internal-ld-pe-fix-se.patch +Patch6009: 0009-release-branch.go1.15-cmd-internal-goobj2-fix-buglet.patch +Patch6010: 0010-release-branch.go1.15-runtime-don-t-adjust-timer-pp-.patch +Patch6011: 0011-release-branch.go1.15-runtime-cgo-fix-Android-build-.patch +Patch6013: 0013-release-branch.go1.15-internal-poll-if-copy_file_ran.patch +Patch6014: 0014-release-branch.go1.15-internal-poll-netpollcheckerr-.patch +Patch6015: 0015-release-branch.go1.15-cmd-compile-do-not-assume-TST-.patch +Patch6016: 0016-release-branch.go1.15-syscall-do-not-overflow-key-me.patch +Patch6017: 0017-release-branch.go1.15-time-correct-unusual-extension.patch +Patch6018: 0018-release-branch.go1.15-cmd-compile-fix-escape-analysi.patch +Patch6019: 0019-release-branch.go1.15-net-http-ignore-connection-clo.patch +Patch6020: 0020-release-branch.go1.15-net-http-add-connections-back-.patch +Patch6021: 0021-release-branch.go1.15-security-encoding-xml-prevent-.patch +Patch6023: 0023-release-branch.go1.15-cmd-go-don-t-report-missing-st.patch +Patch6025: 0025-release-branch.go1.15-cmd-go-internal-modfetch-detec.patch +Patch6026: 0026-release-branch.go1.15-cmd-link-generate-trampoline-f.patch +Patch6027: 0027-release-branch.go1.15-net-http-update-bundled-x-net-.patch +Patch6028: 0028-release-branch.go1.15-net-http-fix-detection-of-Roun.patch +Patch6029: 0029-release-branch.go1.15-build-set-GOPATH-consistently-.patch +Patch6030: 0030-release-branch.go1.15-database-sql-fix-tx-stmt-deadl.patch +Patch6031: 0031-release-branch.go1.15-cmd-compile-disable-shortcircu.patch +Patch6032: 0032-release-branch.go1.15-runtime-non-strict-InlTreeInde.patch +Patch6033: 0033-release-branch.go1.15-cmd-cgo-avoid-exporting-all-sy.patch +Patch6034: 0034-release-branch.go1.15-cmd-link-avoid-exporting-all-s.patch +Patch6035: 0035-release-branch.go1.15-cmd-cgo-remove-unnecessary-spa.patch +Patch6037: 0037-release-branch.go1.15-time-use-offset-and-isDST-when.patch +Patch6038: 0038-release-branch.go1.15-std-update-golang.org-x-net-to.patch +Patch6039: 0039-release-branch.go1.15-runtime-time-disable-preemptio.patch +Patch6040: 0040-release-branch.go1.15-runtime-non-strict-InlTreeInde.patch +Patch6041: 0041-release-branch.go1.15-runtime-pprof-skip-tests-for-A.patch +Patch6043: 0043-release-branch.go1.15-math-big-fix-TestShiftOverlap-.patch +Patch6044: 0044-release-branch.go1.15-math-big-remove-the-s390x-asse.patch +Patch6045: 0045-net-http-fix-hijack-hang-at-abortPendingRead.patch + +Patch9001: 0001-drop-hard-code-cert.patch + %description %{summary}. @@ -381,6 +424,9 @@ fi %files devel -f go-tests.list -f go-misc.list -f go-src.list %changelog +* Fri Jun 18 2021 chenjiankun - 1.15.7-4 +- batch synchronization + * Fri Apr 23 2021 chenjiankun - 1.15.7-3 - fix CVE-2021-27918 -- Gitee